int analyse_instr()

in arch/powerpc/lib/sstep.c [1165:2690]


int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
		  unsigned int instr)
{
	unsigned int opcode, ra, rb, rc, rd, spr, u;
	unsigned long int imm;
	unsigned long int val, val2;
	unsigned int mb, me, sh;
	long ival;

	op->type = COMPUTE;

	opcode = instr >> 26;
	switch (opcode) {
	case 16:	/* bc */
		op->type = BRANCH;
		imm = (signed short)(instr & 0xfffc);
		if ((instr & 2) == 0)
			imm += regs->nip;
		op->val = truncate_if_32bit(regs->msr, imm);
		if (instr & 1)
			op->type |= SETLK;
		if (branch_taken(instr, regs, op))
			op->type |= BRTAKEN;
		return 1;
#ifdef CONFIG_PPC64
	case 17:	/* sc */
		if ((instr & 0xfe2) == 2)
			op->type = SYSCALL;
		else
			op->type = UNKNOWN;
		return 0;
#endif
	case 18:	/* b */
		op->type = BRANCH | BRTAKEN;
		imm = instr & 0x03fffffc;
		if (imm & 0x02000000)
			imm -= 0x04000000;
		if ((instr & 2) == 0)
			imm += regs->nip;
		op->val = truncate_if_32bit(regs->msr, imm);
		if (instr & 1)
			op->type |= SETLK;
		return 1;
	case 19:
		switch ((instr >> 1) & 0x3ff) {
		case 0:		/* mcrf */
			op->type = COMPUTE + SETCC;
			rd = 7 - ((instr >> 23) & 0x7);
			ra = 7 - ((instr >> 18) & 0x7);
			rd *= 4;
			ra *= 4;
			val = (regs->ccr >> ra) & 0xf;
			op->ccval = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
			return 1;

		case 16:	/* bclr */
		case 528:	/* bcctr */
			op->type = BRANCH;
			imm = (instr & 0x400)? regs->ctr: regs->link;
			op->val = truncate_if_32bit(regs->msr, imm);
			if (instr & 1)
				op->type |= SETLK;
			if (branch_taken(instr, regs, op))
				op->type |= BRTAKEN;
			return 1;

		case 18:	/* rfid, scary */
			if (regs->msr & MSR_PR)
				goto priv;
			op->type = RFI;
			return 0;

		case 150:	/* isync */
			op->type = BARRIER | BARRIER_ISYNC;
			return 1;

		case 33:	/* crnor */
		case 129:	/* crandc */
		case 193:	/* crxor */
		case 225:	/* crnand */
		case 257:	/* crand */
		case 289:	/* creqv */
		case 417:	/* crorc */
		case 449:	/* cror */
			op->type = COMPUTE + SETCC;
			ra = (instr >> 16) & 0x1f;
			rb = (instr >> 11) & 0x1f;
			rd = (instr >> 21) & 0x1f;
			ra = (regs->ccr >> (31 - ra)) & 1;
			rb = (regs->ccr >> (31 - rb)) & 1;
			val = (instr >> (6 + ra * 2 + rb)) & 1;
			op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
				(val << (31 - rd));
			return 1;
		}
		break;
	case 31:
		switch ((instr >> 1) & 0x3ff) {
		case 598:	/* sync */
			op->type = BARRIER + BARRIER_SYNC;
#ifdef __powerpc64__
			switch ((instr >> 21) & 3) {
			case 1:		/* lwsync */
				op->type = BARRIER + BARRIER_LWSYNC;
				break;
			case 2:		/* ptesync */
				op->type = BARRIER + BARRIER_PTESYNC;
				break;
			}
#endif
			return 1;

		case 854:	/* eieio */
			op->type = BARRIER + BARRIER_EIEIO;
			return 1;
		}
		break;
	}

	/* Following cases refer to regs->gpr[], so we need all regs */
	if (!FULL_REGS(regs))
		return -1;

	rd = (instr >> 21) & 0x1f;
	ra = (instr >> 16) & 0x1f;
	rb = (instr >> 11) & 0x1f;
	rc = (instr >> 6) & 0x1f;

	switch (opcode) {
#ifdef __powerpc64__
	case 2:		/* tdi */
		if (rd & trap_compare(regs->gpr[ra], (short) instr))
			goto trap;
		return 1;
#endif
	case 3:		/* twi */
		if (rd & trap_compare((int)regs->gpr[ra], (short) instr))
			goto trap;
		return 1;

#ifdef __powerpc64__
	case 4:
		if (!cpu_has_feature(CPU_FTR_ARCH_300))
			return -1;

		switch (instr & 0x3f) {
		case 48:	/* maddhd */
			asm volatile(PPC_MADDHD(%0, %1, %2, %3) :
				     "=r" (op->val) : "r" (regs->gpr[ra]),
				     "r" (regs->gpr[rb]), "r" (regs->gpr[rc]));
			goto compute_done;

		case 49:	/* maddhdu */
			asm volatile(PPC_MADDHDU(%0, %1, %2, %3) :
				     "=r" (op->val) : "r" (regs->gpr[ra]),
				     "r" (regs->gpr[rb]), "r" (regs->gpr[rc]));
			goto compute_done;

		case 51:	/* maddld */
			asm volatile(PPC_MADDLD(%0, %1, %2, %3) :
				     "=r" (op->val) : "r" (regs->gpr[ra]),
				     "r" (regs->gpr[rb]), "r" (regs->gpr[rc]));
			goto compute_done;
		}

		/*
		 * There are other instructions from ISA 3.0 with the same
		 * primary opcode which do not have emulation support yet.
		 */
		return -1;
#endif

	case 7:		/* mulli */
		op->val = regs->gpr[ra] * (short) instr;
		goto compute_done;

	case 8:		/* subfic */
		imm = (short) instr;
		add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1);
		return 1;

	case 10:	/* cmpli */
		imm = (unsigned short) instr;
		val = regs->gpr[ra];
#ifdef __powerpc64__
		if ((rd & 1) == 0)
			val = (unsigned int) val;
#endif
		do_cmp_unsigned(regs, op, val, imm, rd >> 2);
		return 1;

	case 11:	/* cmpi */
		imm = (short) instr;
		val = regs->gpr[ra];
#ifdef __powerpc64__
		if ((rd & 1) == 0)
			val = (int) val;
#endif
		do_cmp_signed(regs, op, val, imm, rd >> 2);
		return 1;

	case 12:	/* addic */
		imm = (short) instr;
		add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
		return 1;

	case 13:	/* addic. */
		imm = (short) instr;
		add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
		set_cr0(regs, op);
		return 1;

	case 14:	/* addi */
		imm = (short) instr;
		if (ra)
			imm += regs->gpr[ra];
		op->val = imm;
		goto compute_done;

	case 15:	/* addis */
		imm = ((short) instr) << 16;
		if (ra)
			imm += regs->gpr[ra];
		op->val = imm;
		goto compute_done;

	case 19:
		if (((instr >> 1) & 0x1f) == 2) {
			/* addpcis */
			imm = (short) (instr & 0xffc1);	/* d0 + d2 fields */
			imm |= (instr >> 15) & 0x3e;	/* d1 field */
			op->val = regs->nip + (imm << 16) + 4;
			goto compute_done;
		}
		op->type = UNKNOWN;
		return 0;

	case 20:	/* rlwimi */
		mb = (instr >> 6) & 0x1f;
		me = (instr >> 1) & 0x1f;
		val = DATA32(regs->gpr[rd]);
		imm = MASK32(mb, me);
		op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm);
		goto logical_done;

	case 21:	/* rlwinm */
		mb = (instr >> 6) & 0x1f;
		me = (instr >> 1) & 0x1f;
		val = DATA32(regs->gpr[rd]);
		op->val = ROTATE(val, rb) & MASK32(mb, me);
		goto logical_done;

	case 23:	/* rlwnm */
		mb = (instr >> 6) & 0x1f;
		me = (instr >> 1) & 0x1f;
		rb = regs->gpr[rb] & 0x1f;
		val = DATA32(regs->gpr[rd]);
		op->val = ROTATE(val, rb) & MASK32(mb, me);
		goto logical_done;

	case 24:	/* ori */
		op->val = regs->gpr[rd] | (unsigned short) instr;
		goto logical_done_nocc;

	case 25:	/* oris */
		imm = (unsigned short) instr;
		op->val = regs->gpr[rd] | (imm << 16);
		goto logical_done_nocc;

	case 26:	/* xori */
		op->val = regs->gpr[rd] ^ (unsigned short) instr;
		goto logical_done_nocc;

	case 27:	/* xoris */
		imm = (unsigned short) instr;
		op->val = regs->gpr[rd] ^ (imm << 16);
		goto logical_done_nocc;

	case 28:	/* andi. */
		op->val = regs->gpr[rd] & (unsigned short) instr;
		set_cr0(regs, op);
		goto logical_done_nocc;

	case 29:	/* andis. */
		imm = (unsigned short) instr;
		op->val = regs->gpr[rd] & (imm << 16);
		set_cr0(regs, op);
		goto logical_done_nocc;

#ifdef __powerpc64__
	case 30:	/* rld* */
		mb = ((instr >> 6) & 0x1f) | (instr & 0x20);
		val = regs->gpr[rd];
		if ((instr & 0x10) == 0) {
			sh = rb | ((instr & 2) << 4);
			val = ROTATE(val, sh);
			switch ((instr >> 2) & 3) {
			case 0:		/* rldicl */
				val &= MASK64_L(mb);
				break;
			case 1:		/* rldicr */
				val &= MASK64_R(mb);
				break;
			case 2:		/* rldic */
				val &= MASK64(mb, 63 - sh);
				break;
			case 3:		/* rldimi */
				imm = MASK64(mb, 63 - sh);
				val = (regs->gpr[ra] & ~imm) |
					(val & imm);
			}
			op->val = val;
			goto logical_done;
		} else {
			sh = regs->gpr[rb] & 0x3f;
			val = ROTATE(val, sh);
			switch ((instr >> 1) & 7) {
			case 0:		/* rldcl */
				op->val = val & MASK64_L(mb);
				goto logical_done;
			case 1:		/* rldcr */
				op->val = val & MASK64_R(mb);
				goto logical_done;
			}
		}
#endif
		op->type = UNKNOWN;	/* illegal instruction */
		return 0;

	case 31:
		/* isel occupies 32 minor opcodes */
		if (((instr >> 1) & 0x1f) == 15) {
			mb = (instr >> 6) & 0x1f; /* bc field */
			val = (regs->ccr >> (31 - mb)) & 1;
			val2 = (ra) ? regs->gpr[ra] : 0;

			op->val = (val) ? val2 : regs->gpr[rb];
			goto compute_done;
		}

		switch ((instr >> 1) & 0x3ff) {
		case 4:		/* tw */
			if (rd == 0x1f ||
			    (rd & trap_compare((int)regs->gpr[ra],
					       (int)regs->gpr[rb])))
				goto trap;
			return 1;
#ifdef __powerpc64__
		case 68:	/* td */
			if (rd & trap_compare(regs->gpr[ra], regs->gpr[rb]))
				goto trap;
			return 1;
#endif
		case 83:	/* mfmsr */
			if (regs->msr & MSR_PR)
				goto priv;
			op->type = MFMSR;
			op->reg = rd;
			return 0;
		case 146:	/* mtmsr */
			if (regs->msr & MSR_PR)
				goto priv;
			op->type = MTMSR;
			op->reg = rd;
			op->val = 0xffffffff & ~(MSR_ME | MSR_LE);
			return 0;
#ifdef CONFIG_PPC64
		case 178:	/* mtmsrd */
			if (regs->msr & MSR_PR)
				goto priv;
			op->type = MTMSR;
			op->reg = rd;
			/* only MSR_EE and MSR_RI get changed if bit 15 set */
			/* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */
			imm = (instr & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
			op->val = imm;
			return 0;
#endif

		case 19:	/* mfcr */
			imm = 0xffffffffUL;
			if ((instr >> 20) & 1) {
				imm = 0xf0000000UL;
				for (sh = 0; sh < 8; ++sh) {
					if (instr & (0x80000 >> sh))
						break;
					imm >>= 4;
				}
			}
			op->val = regs->ccr & imm;
			goto compute_done;

		case 144:	/* mtcrf */
			op->type = COMPUTE + SETCC;
			imm = 0xf0000000UL;
			val = regs->gpr[rd];
			op->ccval = regs->ccr;
			for (sh = 0; sh < 8; ++sh) {
				if (instr & (0x80000 >> sh))
					op->ccval = (op->ccval & ~imm) |
						(val & imm);
				imm >>= 4;
			}
			return 1;

		case 339:	/* mfspr */
			spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
			op->type = MFSPR;
			op->reg = rd;
			op->spr = spr;
			if (spr == SPRN_XER || spr == SPRN_LR ||
			    spr == SPRN_CTR)
				return 1;
			return 0;

		case 467:	/* mtspr */
			spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
			op->type = MTSPR;
			op->val = regs->gpr[rd];
			op->spr = spr;
			if (spr == SPRN_XER || spr == SPRN_LR ||
			    spr == SPRN_CTR)
				return 1;
			return 0;

/*
 * Compare instructions
 */
		case 0:	/* cmp */
			val = regs->gpr[ra];
			val2 = regs->gpr[rb];
#ifdef __powerpc64__
			if ((rd & 1) == 0) {
				/* word (32-bit) compare */
				val = (int) val;
				val2 = (int) val2;
			}
#endif
			do_cmp_signed(regs, op, val, val2, rd >> 2);
			return 1;

		case 32:	/* cmpl */
			val = regs->gpr[ra];
			val2 = regs->gpr[rb];
#ifdef __powerpc64__
			if ((rd & 1) == 0) {
				/* word (32-bit) compare */
				val = (unsigned int) val;
				val2 = (unsigned int) val2;
			}
#endif
			do_cmp_unsigned(regs, op, val, val2, rd >> 2);
			return 1;

		case 508: /* cmpb */
			do_cmpb(regs, op, regs->gpr[rd], regs->gpr[rb]);
			goto logical_done_nocc;

/*
 * Arithmetic instructions
 */
		case 8:	/* subfc */
			add_with_carry(regs, op, rd, ~regs->gpr[ra],
				       regs->gpr[rb], 1);
			goto arith_done;
#ifdef __powerpc64__
		case 9:	/* mulhdu */
			asm("mulhdu %0,%1,%2" : "=r" (op->val) :
			    "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
			goto arith_done;
#endif
		case 10:	/* addc */
			add_with_carry(regs, op, rd, regs->gpr[ra],
				       regs->gpr[rb], 0);
			goto arith_done;

		case 11:	/* mulhwu */
			asm("mulhwu %0,%1,%2" : "=r" (op->val) :
			    "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
			goto arith_done;

		case 40:	/* subf */
			op->val = regs->gpr[rb] - regs->gpr[ra];
			goto arith_done;
#ifdef __powerpc64__
		case 73:	/* mulhd */
			asm("mulhd %0,%1,%2" : "=r" (op->val) :
			    "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
			goto arith_done;
#endif
		case 75:	/* mulhw */
			asm("mulhw %0,%1,%2" : "=r" (op->val) :
			    "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
			goto arith_done;

		case 104:	/* neg */
			op->val = -regs->gpr[ra];
			goto arith_done;

		case 136:	/* subfe */
			add_with_carry(regs, op, rd, ~regs->gpr[ra],
				       regs->gpr[rb], regs->xer & XER_CA);
			goto arith_done;

		case 138:	/* adde */
			add_with_carry(regs, op, rd, regs->gpr[ra],
				       regs->gpr[rb], regs->xer & XER_CA);
			goto arith_done;

		case 200:	/* subfze */
			add_with_carry(regs, op, rd, ~regs->gpr[ra], 0L,
				       regs->xer & XER_CA);
			goto arith_done;

		case 202:	/* addze */
			add_with_carry(regs, op, rd, regs->gpr[ra], 0L,
				       regs->xer & XER_CA);
			goto arith_done;

		case 232:	/* subfme */
			add_with_carry(regs, op, rd, ~regs->gpr[ra], -1L,
				       regs->xer & XER_CA);
			goto arith_done;
#ifdef __powerpc64__
		case 233:	/* mulld */
			op->val = regs->gpr[ra] * regs->gpr[rb];
			goto arith_done;
#endif
		case 234:	/* addme */
			add_with_carry(regs, op, rd, regs->gpr[ra], -1L,
				       regs->xer & XER_CA);
			goto arith_done;

		case 235:	/* mullw */
			op->val = (long)(int) regs->gpr[ra] *
				(int) regs->gpr[rb];

			goto arith_done;
#ifdef __powerpc64__
		case 265:	/* modud */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			op->val = regs->gpr[ra] % regs->gpr[rb];
			goto compute_done;
#endif
		case 266:	/* add */
			op->val = regs->gpr[ra] + regs->gpr[rb];
			goto arith_done;

		case 267:	/* moduw */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			op->val = (unsigned int) regs->gpr[ra] %
				(unsigned int) regs->gpr[rb];
			goto compute_done;
#ifdef __powerpc64__
		case 457:	/* divdu */
			op->val = regs->gpr[ra] / regs->gpr[rb];
			goto arith_done;
#endif
		case 459:	/* divwu */
			op->val = (unsigned int) regs->gpr[ra] /
				(unsigned int) regs->gpr[rb];
			goto arith_done;
#ifdef __powerpc64__
		case 489:	/* divd */
			op->val = (long int) regs->gpr[ra] /
				(long int) regs->gpr[rb];
			goto arith_done;
#endif
		case 491:	/* divw */
			op->val = (int) regs->gpr[ra] /
				(int) regs->gpr[rb];
			goto arith_done;

		case 755:	/* darn */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			switch (ra & 0x3) {
			case 0:
				/* 32-bit conditioned */
				asm volatile(PPC_DARN(%0, 0) : "=r" (op->val));
				goto compute_done;

			case 1:
				/* 64-bit conditioned */
				asm volatile(PPC_DARN(%0, 1) : "=r" (op->val));
				goto compute_done;

			case 2:
				/* 64-bit raw */
				asm volatile(PPC_DARN(%0, 2) : "=r" (op->val));
				goto compute_done;
			}

			return -1;
#ifdef __powerpc64__
		case 777:	/* modsd */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			op->val = (long int) regs->gpr[ra] %
				(long int) regs->gpr[rb];
			goto compute_done;
#endif
		case 779:	/* modsw */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			op->val = (int) regs->gpr[ra] %
				(int) regs->gpr[rb];
			goto compute_done;


/*
 * Logical instructions
 */
		case 26:	/* cntlzw */
			val = (unsigned int) regs->gpr[rd];
			op->val = ( val ? __builtin_clz(val) : 32 );
			goto logical_done;
#ifdef __powerpc64__
		case 58:	/* cntlzd */
			val = regs->gpr[rd];
			op->val = ( val ? __builtin_clzl(val) : 64 );
			goto logical_done;
#endif
		case 28:	/* and */
			op->val = regs->gpr[rd] & regs->gpr[rb];
			goto logical_done;

		case 60:	/* andc */
			op->val = regs->gpr[rd] & ~regs->gpr[rb];
			goto logical_done;

		case 122:	/* popcntb */
			do_popcnt(regs, op, regs->gpr[rd], 8);
			goto logical_done_nocc;

		case 124:	/* nor */
			op->val = ~(regs->gpr[rd] | regs->gpr[rb]);
			goto logical_done;

		case 154:	/* prtyw */
			do_prty(regs, op, regs->gpr[rd], 32);
			goto logical_done_nocc;

		case 186:	/* prtyd */
			do_prty(regs, op, regs->gpr[rd], 64);
			goto logical_done_nocc;
#ifdef CONFIG_PPC64
		case 252:	/* bpermd */
			do_bpermd(regs, op, regs->gpr[rd], regs->gpr[rb]);
			goto logical_done_nocc;
#endif
		case 284:	/* xor */
			op->val = ~(regs->gpr[rd] ^ regs->gpr[rb]);
			goto logical_done;

		case 316:	/* xor */
			op->val = regs->gpr[rd] ^ regs->gpr[rb];
			goto logical_done;

		case 378:	/* popcntw */
			do_popcnt(regs, op, regs->gpr[rd], 32);
			goto logical_done_nocc;

		case 412:	/* orc */
			op->val = regs->gpr[rd] | ~regs->gpr[rb];
			goto logical_done;

		case 444:	/* or */
			op->val = regs->gpr[rd] | regs->gpr[rb];
			goto logical_done;

		case 476:	/* nand */
			op->val = ~(regs->gpr[rd] & regs->gpr[rb]);
			goto logical_done;
#ifdef CONFIG_PPC64
		case 506:	/* popcntd */
			do_popcnt(regs, op, regs->gpr[rd], 64);
			goto logical_done_nocc;
#endif
		case 538:	/* cnttzw */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			val = (unsigned int) regs->gpr[rd];
			op->val = (val ? __builtin_ctz(val) : 32);
			goto logical_done;
#ifdef __powerpc64__
		case 570:	/* cnttzd */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			val = regs->gpr[rd];
			op->val = (val ? __builtin_ctzl(val) : 64);
			goto logical_done;
#endif
		case 922:	/* extsh */
			op->val = (signed short) regs->gpr[rd];
			goto logical_done;

		case 954:	/* extsb */
			op->val = (signed char) regs->gpr[rd];
			goto logical_done;
#ifdef __powerpc64__
		case 986:	/* extsw */
			op->val = (signed int) regs->gpr[rd];
			goto logical_done;
#endif

/*
 * Shift instructions
 */
		case 24:	/* slw */
			sh = regs->gpr[rb] & 0x3f;
			if (sh < 32)
				op->val = (regs->gpr[rd] << sh) & 0xffffffffUL;
			else
				op->val = 0;
			goto logical_done;

		case 536:	/* srw */
			sh = regs->gpr[rb] & 0x3f;
			if (sh < 32)
				op->val = (regs->gpr[rd] & 0xffffffffUL) >> sh;
			else
				op->val = 0;
			goto logical_done;

		case 792:	/* sraw */
			op->type = COMPUTE + SETREG + SETXER;
			sh = regs->gpr[rb] & 0x3f;
			ival = (signed int) regs->gpr[rd];
			op->val = ival >> (sh < 32 ? sh : 31);
			op->xerval = regs->xer;
			if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0))
				op->xerval |= XER_CA;
			else
				op->xerval &= ~XER_CA;
			set_ca32(op, op->xerval & XER_CA);
			goto logical_done;

		case 824:	/* srawi */
			op->type = COMPUTE + SETREG + SETXER;
			sh = rb;
			ival = (signed int) regs->gpr[rd];
			op->val = ival >> sh;
			op->xerval = regs->xer;
			if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
				op->xerval |= XER_CA;
			else
				op->xerval &= ~XER_CA;
			set_ca32(op, op->xerval & XER_CA);
			goto logical_done;

#ifdef __powerpc64__
		case 27:	/* sld */
			sh = regs->gpr[rb] & 0x7f;
			if (sh < 64)
				op->val = regs->gpr[rd] << sh;
			else
				op->val = 0;
			goto logical_done;

		case 539:	/* srd */
			sh = regs->gpr[rb] & 0x7f;
			if (sh < 64)
				op->val = regs->gpr[rd] >> sh;
			else
				op->val = 0;
			goto logical_done;

		case 794:	/* srad */
			op->type = COMPUTE + SETREG + SETXER;
			sh = regs->gpr[rb] & 0x7f;
			ival = (signed long int) regs->gpr[rd];
			op->val = ival >> (sh < 64 ? sh : 63);
			op->xerval = regs->xer;
			if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0))
				op->xerval |= XER_CA;
			else
				op->xerval &= ~XER_CA;
			set_ca32(op, op->xerval & XER_CA);
			goto logical_done;

		case 826:	/* sradi with sh_5 = 0 */
		case 827:	/* sradi with sh_5 = 1 */
			op->type = COMPUTE + SETREG + SETXER;
			sh = rb | ((instr & 2) << 4);
			ival = (signed long int) regs->gpr[rd];
			op->val = ival >> sh;
			op->xerval = regs->xer;
			if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
				op->xerval |= XER_CA;
			else
				op->xerval &= ~XER_CA;
			set_ca32(op, op->xerval & XER_CA);
			goto logical_done;

		case 890:	/* extswsli with sh_5 = 0 */
		case 891:	/* extswsli with sh_5 = 1 */
			if (!cpu_has_feature(CPU_FTR_ARCH_300))
				return -1;
			op->type = COMPUTE + SETREG;
			sh = rb | ((instr & 2) << 4);
			val = (signed int) regs->gpr[rd];
			if (sh)
				op->val = ROTATE(val, sh) & MASK64(0, 63 - sh);
			else
				op->val = val;
			goto logical_done;

#endif /* __powerpc64__ */

/*
 * Cache instructions
 */
		case 54:	/* dcbst */
			op->type = MKOP(CACHEOP, DCBST, 0);
			op->ea = xform_ea(instr, regs);
			return 0;

		case 86:	/* dcbf */
			op->type = MKOP(CACHEOP, DCBF, 0);
			op->ea = xform_ea(instr, regs);
			return 0;

		case 246:	/* dcbtst */
			op->type = MKOP(CACHEOP, DCBTST, 0);
			op->ea = xform_ea(instr, regs);
			op->reg = rd;
			return 0;

		case 278:	/* dcbt */
			op->type = MKOP(CACHEOP, DCBTST, 0);
			op->ea = xform_ea(instr, regs);
			op->reg = rd;
			return 0;

		case 982:	/* icbi */
			op->type = MKOP(CACHEOP, ICBI, 0);
			op->ea = xform_ea(instr, regs);
			return 0;

		case 1014:	/* dcbz */
			op->type = MKOP(CACHEOP, DCBZ, 0);
			op->ea = xform_ea(instr, regs);
			return 0;
		}
		break;
	}

/*
 * Loads and stores.
 */
	op->type = UNKNOWN;
	op->update_reg = ra;
	op->reg = rd;
	op->val = regs->gpr[rd];
	u = (instr >> 20) & UPDATE;
	op->vsx_flags = 0;

	switch (opcode) {
	case 31:
		u = instr & UPDATE;
		op->ea = xform_ea(instr, regs);
		switch ((instr >> 1) & 0x3ff) {
		case 20:	/* lwarx */
			op->type = MKOP(LARX, 0, 4);
			break;

		case 150:	/* stwcx. */
			op->type = MKOP(STCX, 0, 4);
			break;

#ifdef __powerpc64__
		case 84:	/* ldarx */
			op->type = MKOP(LARX, 0, 8);
			break;

		case 214:	/* stdcx. */
			op->type = MKOP(STCX, 0, 8);
			break;

		case 52:	/* lbarx */
			op->type = MKOP(LARX, 0, 1);
			break;

		case 694:	/* stbcx. */
			op->type = MKOP(STCX, 0, 1);
			break;

		case 116:	/* lharx */
			op->type = MKOP(LARX, 0, 2);
			break;

		case 726:	/* sthcx. */
			op->type = MKOP(STCX, 0, 2);
			break;

		case 276:	/* lqarx */
			if (!((rd & 1) || rd == ra || rd == rb))
				op->type = MKOP(LARX, 0, 16);
			break;

		case 182:	/* stqcx. */
			if (!(rd & 1))
				op->type = MKOP(STCX, 0, 16);
			break;
#endif

		case 23:	/* lwzx */
		case 55:	/* lwzux */
			op->type = MKOP(LOAD, u, 4);
			break;

		case 87:	/* lbzx */
		case 119:	/* lbzux */
			op->type = MKOP(LOAD, u, 1);
			break;

#ifdef CONFIG_ALTIVEC
		/*
		 * Note: for the load/store vector element instructions,
		 * bits of the EA say which field of the VMX register to use.
		 */
		case 7:		/* lvebx */
			op->type = MKOP(LOAD_VMX, 0, 1);
			op->element_size = 1;
			break;

		case 39:	/* lvehx */
			op->type = MKOP(LOAD_VMX, 0, 2);
			op->element_size = 2;
			break;

		case 71:	/* lvewx */
			op->type = MKOP(LOAD_VMX, 0, 4);
			op->element_size = 4;
			break;

		case 103:	/* lvx */
		case 359:	/* lvxl */
			op->type = MKOP(LOAD_VMX, 0, 16);
			op->element_size = 16;
			break;

		case 135:	/* stvebx */
			op->type = MKOP(STORE_VMX, 0, 1);
			op->element_size = 1;
			break;

		case 167:	/* stvehx */
			op->type = MKOP(STORE_VMX, 0, 2);
			op->element_size = 2;
			break;

		case 199:	/* stvewx */
			op->type = MKOP(STORE_VMX, 0, 4);
			op->element_size = 4;
			break;

		case 231:	/* stvx */
		case 487:	/* stvxl */
			op->type = MKOP(STORE_VMX, 0, 16);
			break;
#endif /* CONFIG_ALTIVEC */

#ifdef __powerpc64__
		case 21:	/* ldx */
		case 53:	/* ldux */
			op->type = MKOP(LOAD, u, 8);
			break;

		case 149:	/* stdx */
		case 181:	/* stdux */
			op->type = MKOP(STORE, u, 8);
			break;
#endif

		case 151:	/* stwx */
		case 183:	/* stwux */
			op->type = MKOP(STORE, u, 4);
			break;

		case 215:	/* stbx */
		case 247:	/* stbux */
			op->type = MKOP(STORE, u, 1);
			break;

		case 279:	/* lhzx */
		case 311:	/* lhzux */
			op->type = MKOP(LOAD, u, 2);
			break;

#ifdef __powerpc64__
		case 341:	/* lwax */
		case 373:	/* lwaux */
			op->type = MKOP(LOAD, SIGNEXT | u, 4);
			break;
#endif

		case 343:	/* lhax */
		case 375:	/* lhaux */
			op->type = MKOP(LOAD, SIGNEXT | u, 2);
			break;

		case 407:	/* sthx */
		case 439:	/* sthux */
			op->type = MKOP(STORE, u, 2);
			break;

#ifdef __powerpc64__
		case 532:	/* ldbrx */
			op->type = MKOP(LOAD, BYTEREV, 8);
			break;

#endif
		case 533:	/* lswx */
			op->type = MKOP(LOAD_MULTI, 0, regs->xer & 0x7f);
			break;

		case 534:	/* lwbrx */
			op->type = MKOP(LOAD, BYTEREV, 4);
			break;

		case 597:	/* lswi */
			if (rb == 0)
				rb = 32;	/* # bytes to load */
			op->type = MKOP(LOAD_MULTI, 0, rb);
			op->ea = ra ? regs->gpr[ra] : 0;
			break;

#ifdef CONFIG_PPC_FPU
		case 535:	/* lfsx */
		case 567:	/* lfsux */
			op->type = MKOP(LOAD_FP, u | FPCONV, 4);
			break;

		case 599:	/* lfdx */
		case 631:	/* lfdux */
			op->type = MKOP(LOAD_FP, u, 8);
			break;

		case 663:	/* stfsx */
		case 695:	/* stfsux */
			op->type = MKOP(STORE_FP, u | FPCONV, 4);
			break;

		case 727:	/* stfdx */
		case 759:	/* stfdux */
			op->type = MKOP(STORE_FP, u, 8);
			break;

#ifdef __powerpc64__
		case 791:	/* lfdpx */
			op->type = MKOP(LOAD_FP, 0, 16);
			break;

		case 855:	/* lfiwax */
			op->type = MKOP(LOAD_FP, SIGNEXT, 4);
			break;

		case 887:	/* lfiwzx */
			op->type = MKOP(LOAD_FP, 0, 4);
			break;

		case 919:	/* stfdpx */
			op->type = MKOP(STORE_FP, 0, 16);
			break;

		case 983:	/* stfiwx */
			op->type = MKOP(STORE_FP, 0, 4);
			break;
#endif /* __powerpc64 */
#endif /* CONFIG_PPC_FPU */

#ifdef __powerpc64__
		case 660:	/* stdbrx */
			op->type = MKOP(STORE, BYTEREV, 8);
			op->val = byterev_8(regs->gpr[rd]);
			break;

#endif
		case 661:	/* stswx */
			op->type = MKOP(STORE_MULTI, 0, regs->xer & 0x7f);
			break;

		case 662:	/* stwbrx */
			op->type = MKOP(STORE, BYTEREV, 4);
			op->val = byterev_4(regs->gpr[rd]);
			break;

		case 725:	/* stswi */
			if (rb == 0)
				rb = 32;	/* # bytes to store */
			op->type = MKOP(STORE_MULTI, 0, rb);
			op->ea = ra ? regs->gpr[ra] : 0;
			break;

		case 790:	/* lhbrx */
			op->type = MKOP(LOAD, BYTEREV, 2);
			break;

		case 918:	/* sthbrx */
			op->type = MKOP(STORE, BYTEREV, 2);
			op->val = byterev_2(regs->gpr[rd]);
			break;

#ifdef CONFIG_VSX
		case 12:	/* lxsiwzx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 4);
			op->element_size = 8;
			break;

		case 76:	/* lxsiwax */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, SIGNEXT, 4);
			op->element_size = 8;
			break;

		case 140:	/* stxsiwx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 4);
			op->element_size = 8;
			break;

		case 268:	/* lxvx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 16);
			op->element_size = 16;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 269:	/* lxvl */
		case 301: {	/* lxvll */
			int nb;
			op->reg = rd | ((instr & 1) << 5);
			op->ea = ra ? regs->gpr[ra] : 0;
			nb = regs->gpr[rb] & 0xff;
			if (nb > 16)
				nb = 16;
			op->type = MKOP(LOAD_VSX, 0, nb);
			op->element_size = 16;
			op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
				VSX_CHECK_VEC;
			break;
		}
		case 332:	/* lxvdsx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 8);
			op->element_size = 8;
			op->vsx_flags = VSX_SPLAT;
			break;

		case 364:	/* lxvwsx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 4);
			op->element_size = 4;
			op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC;
			break;

		case 396:	/* stxvx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 16);
			op->element_size = 16;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 397:	/* stxvl */
		case 429: {	/* stxvll */
			int nb;
			op->reg = rd | ((instr & 1) << 5);
			op->ea = ra ? regs->gpr[ra] : 0;
			nb = regs->gpr[rb] & 0xff;
			if (nb > 16)
				nb = 16;
			op->type = MKOP(STORE_VSX, 0, nb);
			op->element_size = 16;
			op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) |
				VSX_CHECK_VEC;
			break;
		}
		case 524:	/* lxsspx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 4);
			op->element_size = 8;
			op->vsx_flags = VSX_FPCONV;
			break;

		case 588:	/* lxsdx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 8);
			op->element_size = 8;
			break;

		case 652:	/* stxsspx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 4);
			op->element_size = 8;
			op->vsx_flags = VSX_FPCONV;
			break;

		case 716:	/* stxsdx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 8);
			op->element_size = 8;
			break;

		case 780:	/* lxvw4x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 16);
			op->element_size = 4;
			break;

		case 781:	/* lxsibzx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 1);
			op->element_size = 8;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 812:	/* lxvh8x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 16);
			op->element_size = 2;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 813:	/* lxsihzx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 2);
			op->element_size = 8;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 844:	/* lxvd2x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 16);
			op->element_size = 8;
			break;

		case 876:	/* lxvb16x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(LOAD_VSX, 0, 16);
			op->element_size = 1;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 908:	/* stxvw4x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 16);
			op->element_size = 4;
			break;

		case 909:	/* stxsibx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 1);
			op->element_size = 8;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 940:	/* stxvh8x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 16);
			op->element_size = 2;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 941:	/* stxsihx */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 2);
			op->element_size = 8;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 972:	/* stxvd2x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 16);
			op->element_size = 8;
			break;

		case 1004:	/* stxvb16x */
			op->reg = rd | ((instr & 1) << 5);
			op->type = MKOP(STORE_VSX, 0, 16);
			op->element_size = 1;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

#endif /* CONFIG_VSX */
		}
		break;

	case 32:	/* lwz */
	case 33:	/* lwzu */
		op->type = MKOP(LOAD, u, 4);
		op->ea = dform_ea(instr, regs);
		break;

	case 34:	/* lbz */
	case 35:	/* lbzu */
		op->type = MKOP(LOAD, u, 1);
		op->ea = dform_ea(instr, regs);
		break;

	case 36:	/* stw */
	case 37:	/* stwu */
		op->type = MKOP(STORE, u, 4);
		op->ea = dform_ea(instr, regs);
		break;

	case 38:	/* stb */
	case 39:	/* stbu */
		op->type = MKOP(STORE, u, 1);
		op->ea = dform_ea(instr, regs);
		break;

	case 40:	/* lhz */
	case 41:	/* lhzu */
		op->type = MKOP(LOAD, u, 2);
		op->ea = dform_ea(instr, regs);
		break;

	case 42:	/* lha */
	case 43:	/* lhau */
		op->type = MKOP(LOAD, SIGNEXT | u, 2);
		op->ea = dform_ea(instr, regs);
		break;

	case 44:	/* sth */
	case 45:	/* sthu */
		op->type = MKOP(STORE, u, 2);
		op->ea = dform_ea(instr, regs);
		break;

	case 46:	/* lmw */
		if (ra >= rd)
			break;		/* invalid form, ra in range to load */
		op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd));
		op->ea = dform_ea(instr, regs);
		break;

	case 47:	/* stmw */
		op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd));
		op->ea = dform_ea(instr, regs);
		break;

#ifdef CONFIG_PPC_FPU
	case 48:	/* lfs */
	case 49:	/* lfsu */
		op->type = MKOP(LOAD_FP, u | FPCONV, 4);
		op->ea = dform_ea(instr, regs);
		break;

	case 50:	/* lfd */
	case 51:	/* lfdu */
		op->type = MKOP(LOAD_FP, u, 8);
		op->ea = dform_ea(instr, regs);
		break;

	case 52:	/* stfs */
	case 53:	/* stfsu */
		op->type = MKOP(STORE_FP, u | FPCONV, 4);
		op->ea = dform_ea(instr, regs);
		break;

	case 54:	/* stfd */
	case 55:	/* stfdu */
		op->type = MKOP(STORE_FP, u, 8);
		op->ea = dform_ea(instr, regs);
		break;
#endif

#ifdef __powerpc64__
	case 56:	/* lq */
		if (!((rd & 1) || (rd == ra)))
			op->type = MKOP(LOAD, 0, 16);
		op->ea = dqform_ea(instr, regs);
		break;
#endif

#ifdef CONFIG_VSX
	case 57:	/* lfdp, lxsd, lxssp */
		op->ea = dsform_ea(instr, regs);
		switch (instr & 3) {
		case 0:		/* lfdp */
			if (rd & 1)
				break;		/* reg must be even */
			op->type = MKOP(LOAD_FP, 0, 16);
			break;
		case 2:		/* lxsd */
			op->reg = rd + 32;
			op->type = MKOP(LOAD_VSX, 0, 8);
			op->element_size = 8;
			op->vsx_flags = VSX_CHECK_VEC;
			break;
		case 3:		/* lxssp */
			op->reg = rd + 32;
			op->type = MKOP(LOAD_VSX, 0, 4);
			op->element_size = 8;
			op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
			break;
		}
		break;
#endif /* CONFIG_VSX */

#ifdef __powerpc64__
	case 58:	/* ld[u], lwa */
		op->ea = dsform_ea(instr, regs);
		switch (instr & 3) {
		case 0:		/* ld */
			op->type = MKOP(LOAD, 0, 8);
			break;
		case 1:		/* ldu */
			op->type = MKOP(LOAD, UPDATE, 8);
			break;
		case 2:		/* lwa */
			op->type = MKOP(LOAD, SIGNEXT, 4);
			break;
		}
		break;
#endif

#ifdef CONFIG_VSX
	case 61:	/* stfdp, lxv, stxsd, stxssp, stxv */
		switch (instr & 7) {
		case 0:		/* stfdp with LSB of DS field = 0 */
		case 4:		/* stfdp with LSB of DS field = 1 */
			op->ea = dsform_ea(instr, regs);
			op->type = MKOP(STORE_FP, 0, 16);
			break;

		case 1:		/* lxv */
			op->ea = dqform_ea(instr, regs);
			if (instr & 8)
				op->reg = rd + 32;
			op->type = MKOP(LOAD_VSX, 0, 16);
			op->element_size = 16;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 2:		/* stxsd with LSB of DS field = 0 */
		case 6:		/* stxsd with LSB of DS field = 1 */
			op->ea = dsform_ea(instr, regs);
			op->reg = rd + 32;
			op->type = MKOP(STORE_VSX, 0, 8);
			op->element_size = 8;
			op->vsx_flags = VSX_CHECK_VEC;
			break;

		case 3:		/* stxssp with LSB of DS field = 0 */
		case 7:		/* stxssp with LSB of DS field = 1 */
			op->ea = dsform_ea(instr, regs);
			op->reg = rd + 32;
			op->type = MKOP(STORE_VSX, 0, 4);
			op->element_size = 8;
			op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
			break;

		case 5:		/* stxv */
			op->ea = dqform_ea(instr, regs);
			if (instr & 8)
				op->reg = rd + 32;
			op->type = MKOP(STORE_VSX, 0, 16);
			op->element_size = 16;
			op->vsx_flags = VSX_CHECK_VEC;
			break;
		}
		break;
#endif /* CONFIG_VSX */

#ifdef __powerpc64__
	case 62:	/* std[u] */
		op->ea = dsform_ea(instr, regs);
		switch (instr & 3) {
		case 0:		/* std */
			op->type = MKOP(STORE, 0, 8);
			break;
		case 1:		/* stdu */
			op->type = MKOP(STORE, UPDATE, 8);
			break;
		case 2:		/* stq */
			if (!(rd & 1))
				op->type = MKOP(STORE, 0, 16);
			break;
		}
		break;
#endif /* __powerpc64__ */

	}

#ifdef CONFIG_VSX
	if ((GETTYPE(op->type) == LOAD_VSX ||
	     GETTYPE(op->type) == STORE_VSX) &&
	    !cpu_has_feature(CPU_FTR_VSX)) {
		return -1;
	}
#endif /* CONFIG_VSX */

	return 0;

 logical_done:
	if (instr & 1)
		set_cr0(regs, op);
 logical_done_nocc:
	op->reg = ra;
	op->type |= SETREG;
	return 1;

 arith_done:
	if (instr & 1)
		set_cr0(regs, op);
 compute_done:
	op->reg = rd;
	op->type |= SETREG;
	return 1;

 priv:
	op->type = INTERRUPT | 0x700;
	op->val = SRR1_PROGPRIV;
	return 0;

 trap:
	op->type = INTERRUPT | 0x700;
	op->val = SRR1_PROGTRAP;
	return 0;
}