^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Single-step support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/prefetch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/sstep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/cpu_has_feature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/cputable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/disassemble.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) extern char system_call_common[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) extern char system_call_vectored_emulate[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* Bits in SRR1 that are copied from MSR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define MSR_MASK 0xffffffff87c0ffffUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define MSR_MASK 0x87c0ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Bits in XER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define XER_SO 0x80000000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define XER_OV 0x40000000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define XER_CA 0x20000000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define XER_OV32 0x00080000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define XER_CA32 0x00040000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #ifdef CONFIG_PPC_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Functions in ldstfp.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) extern void get_fpr(int rn, double *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) extern void put_fpr(int rn, const double *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) extern void get_vr(int rn, __vector128 *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) extern void put_vr(int rn, __vector128 *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) extern void load_vsrn(int vsr, const void *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) extern void store_vsrn(int vsr, void *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) extern void conv_sp_to_dp(const float *sp, double *dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) extern void conv_dp_to_sp(const double *dp, float *sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Functions in quad.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) extern int do_lq(unsigned long ea, unsigned long *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) extern int do_stq(unsigned long ea, unsigned long val0, unsigned long val1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) extern int do_lqarx(unsigned long ea, unsigned long *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) extern int do_stqcx(unsigned long ea, unsigned long val0, unsigned long val1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int *crp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #ifdef __LITTLE_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IS_LE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define IS_BE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define IS_LE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IS_BE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Emulate the truncation of 64 bit values in 32-bit mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static nokprobe_inline unsigned long truncate_if_32bit(unsigned long msr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if ((msr & MSR_64BIT) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) val &= 0xffffffffUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Determine whether a conditional branch instruction would branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static nokprobe_inline int branch_taken(unsigned int instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct instruction_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int bo = (instr >> 21) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int bi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if ((bo & 4) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* decrement counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) op->type |= DECCTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (((bo >> 1) & 1) ^ (regs->ctr == 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if ((bo & 0x10) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* check bit from CR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bi = (instr >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static nokprobe_inline long address_ok(struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned long ea, int nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (access_ok((void __user *)ea, nb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (access_ok((void __user *)ea, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Access overlaps the end of the user region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) regs->dar = TASK_SIZE_MAX - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Calculate effective address for a D-form instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static nokprobe_inline unsigned long dform_ea(unsigned int instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) const struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned long ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ra = (instr >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ea = (signed short) instr; /* sign-extend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ea += regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Calculate effective address for a DS-form instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static nokprobe_inline unsigned long dsform_ea(unsigned int instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) const struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned long ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ra = (instr >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ea = (signed short) (instr & ~3); /* sign-extend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ea += regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Calculate effective address for a DQ-form instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static nokprobe_inline unsigned long dqform_ea(unsigned int instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsigned long ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ra = (instr >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ea = (signed short) (instr & ~0xf); /* sign-extend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ea += regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #endif /* __powerpc64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * Calculate effective address for an X-form instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static nokprobe_inline unsigned long xform_ea(unsigned int instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) const struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int ra, rb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned long ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ra = (instr >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) rb = (instr >> 11) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ea = regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ea += regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Calculate effective address for a MLS:D-form / 8LS:D-form
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * prefixed instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static nokprobe_inline unsigned long mlsd_8lsd_ea(unsigned int instr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned int suffix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) const struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int ra, prefix_r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned int dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned long ea, d0, d1, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) prefix_r = GET_PREFIX_R(instr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ra = GET_PREFIX_RA(suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) d0 = instr & 0x3ffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) d1 = suffix & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) d = (d0 << 16) | d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * sign extend a 34 bit number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dd = (unsigned int)(d >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ea = (signed int)dd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ea = (ea << 2) | (d & 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (!prefix_r && ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ea += regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) else if (!prefix_r && !ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ; /* Leave ea as is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) else if (prefix_r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ea += regs->nip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * (prefix_r && ra) is an invalid form. Should already be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * checked for by caller!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Return the largest power of 2, not greater than sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * such that x is a multiple of it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static nokprobe_inline unsigned long max_align(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) x |= sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return x & -x; /* isolates rightmost bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static nokprobe_inline unsigned long byterev_2(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static nokprobe_inline unsigned long byterev_4(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ((x & 0xff00) << 8) | ((x & 0xff) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static nokprobe_inline unsigned long byterev_8(unsigned long x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return (byterev_4(x) << 32) | byterev_4(x >> 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static nokprobe_inline void do_byte_reverse(void *ptr, int nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) switch (nb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *(u16 *)ptr = byterev_2(*(u16 *)ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *(u32 *)ptr = byterev_4(*(u32 *)ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *(unsigned long *)ptr = byterev_8(*(unsigned long *)ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case 16: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned long *up = (unsigned long *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) tmp = byterev_8(up[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) up[0] = byterev_8(up[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) up[1] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static nokprobe_inline int read_mem_aligned(unsigned long *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) unsigned long x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) switch (nb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) err = __get_user(x, (unsigned char __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) err = __get_user(x, (unsigned short __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) err = __get_user(x, (unsigned int __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) err = __get_user(x, (unsigned long __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *dest = x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * Copy from userspace to a buffer, using the largest possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * aligned accesses, up to sizeof(long).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static nokprobe_inline int copy_mem_in(u8 *dest, unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) for (; nb > 0; nb -= c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) c = max_align(ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (c > nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) c = max_align(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) err = __get_user(*dest, (unsigned char __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) err = __get_user(*(u16 *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) (unsigned short __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) err = __get_user(*(u32 *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) (unsigned int __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) err = __get_user(*(unsigned long *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) (unsigned long __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dest += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ea += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static nokprobe_inline int read_mem_unaligned(unsigned long *dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) unsigned long ul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u8 b[sizeof(unsigned long)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u.ul = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) i = IS_BE ? sizeof(unsigned long) - nb : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) err = copy_mem_in(&u.b[i], ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *dest = u.ul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * Read memory at address ea for nb bytes, return 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * or -EFAULT if an error occurred. N.B. nb must be 1, 2, 4 or 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * If nb < sizeof(long), the result is right-justified on BE systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int read_mem(unsigned long *dest, unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!address_ok(regs, ea, nb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if ((ea & (nb - 1)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return read_mem_aligned(dest, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return read_mem_unaligned(dest, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) NOKPROBE_SYMBOL(read_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static nokprobe_inline int write_mem_aligned(unsigned long val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) switch (nb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) err = __put_user(val, (unsigned char __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) err = __put_user(val, (unsigned short __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) err = __put_user(val, (unsigned int __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) err = __put_user(val, (unsigned long __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * Copy from a buffer to userspace, using the largest possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * aligned accesses, up to sizeof(long).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static nokprobe_inline int copy_mem_out(u8 *dest, unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) for (; nb > 0; nb -= c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) c = max_align(ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (c > nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) c = max_align(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) err = __put_user(*dest, (unsigned char __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) err = __put_user(*(u16 *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) (unsigned short __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) err = __put_user(*(u32 *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) (unsigned int __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) err = __put_user(*(unsigned long *)dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) (unsigned long __user *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dest += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ea += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static nokprobe_inline int write_mem_unaligned(unsigned long val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) unsigned long ul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) u8 b[sizeof(unsigned long)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u.ul = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) i = IS_BE ? sizeof(unsigned long) - nb : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return copy_mem_out(&u.b[i], ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Write memory at address ea for nb bytes, return 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * or -EFAULT if an error occurred. N.B. nb must be 1, 2, 4 or 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int write_mem(unsigned long val, unsigned long ea, int nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!address_ok(regs, ea, nb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if ((ea & (nb - 1)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return write_mem_aligned(val, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return write_mem_unaligned(val, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) NOKPROBE_SYMBOL(write_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) #ifdef CONFIG_PPC_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * These access either the real FP register or the image in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * thread_struct, depending on regs->msr & MSR_FP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int do_fp_load(struct instruction_op *op, unsigned long ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct pt_regs *regs, bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int err, rn, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned int u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) float f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) double d[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) unsigned long l[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) u8 b[2 * sizeof(double)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) nb = GETSIZE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (!address_ok(regs, ea, nb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) rn = op->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) err = copy_mem_in(u.b, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (unlikely(cross_endian)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) do_byte_reverse(u.b, min(nb, 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (nb == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) do_byte_reverse(&u.b[8], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (nb == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (op->type & FPCONV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) conv_sp_to_dp(&u.f, &u.d[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) else if (op->type & SIGNEXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) u.l[0] = u.i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) u.l[0] = u.u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (regs->msr & MSR_FP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) put_fpr(rn, &u.d[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) current->thread.TS_FPR(rn) = u.l[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (nb == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* lfdp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) rn |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (regs->msr & MSR_FP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) put_fpr(rn, &u.d[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) current->thread.TS_FPR(rn) = u.l[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) NOKPROBE_SYMBOL(do_fp_load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int do_fp_store(struct instruction_op *op, unsigned long ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct pt_regs *regs, bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int rn, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) unsigned int u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) float f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) double d[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned long l[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) u8 b[2 * sizeof(double)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) nb = GETSIZE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (!address_ok(regs, ea, nb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rn = op->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (regs->msr & MSR_FP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) get_fpr(rn, &u.d[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) u.l[0] = current->thread.TS_FPR(rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (nb == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (op->type & FPCONV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) conv_dp_to_sp(&u.d[0], &u.f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) u.u = u.l[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (nb == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) rn |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (regs->msr & MSR_FP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) get_fpr(rn, &u.d[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) u.l[1] = current->thread.TS_FPR(rn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (unlikely(cross_endian)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) do_byte_reverse(u.b, min(nb, 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (nb == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) do_byte_reverse(&u.b[8], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return copy_mem_out(u.b, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) NOKPROBE_SYMBOL(do_fp_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #ifdef CONFIG_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /* For Altivec/VMX, no need to worry about alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static nokprobe_inline int do_vec_load(int rn, unsigned long ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int size, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) __vector128 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) u8 b[sizeof(__vector128)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) } u = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!address_ok(regs, ea & ~0xfUL, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* align to multiple of size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ea &= ~(size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) err = copy_mem_in(&u.b[ea & 0xf], ea, size, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (unlikely(cross_endian))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) do_byte_reverse(&u.b[ea & 0xf], size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (regs->msr & MSR_VEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) put_vr(rn, &u.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) current->thread.vr_state.vr[rn] = u.v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static nokprobe_inline int do_vec_store(int rn, unsigned long ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int size, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) __vector128 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) u8 b[sizeof(__vector128)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) } u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!address_ok(regs, ea & ~0xfUL, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* align to multiple of size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ea &= ~(size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (regs->msr & MSR_VEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) get_vr(rn, &u.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) u.v = current->thread.vr_state.vr[rn];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (unlikely(cross_endian))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) do_byte_reverse(&u.b[ea & 0xf], size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return copy_mem_out(&u.b[ea & 0xf], ea, size, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) #endif /* CONFIG_ALTIVEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static nokprobe_inline int emulate_lq(struct pt_regs *regs, unsigned long ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int reg, bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (!address_ok(regs, ea, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* if aligned, should be atomic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if ((ea & 0xf) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) err = do_lq(ea, ®s->gpr[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) err = read_mem(®s->gpr[reg + IS_LE], ea, 8, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) err = read_mem(®s->gpr[reg + IS_BE], ea + 8, 8, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!err && unlikely(cross_endian))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) do_byte_reverse(®s->gpr[reg], 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) int reg, bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) unsigned long vals[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (!address_ok(regs, ea, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) vals[0] = regs->gpr[reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) vals[1] = regs->gpr[reg + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (unlikely(cross_endian))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) do_byte_reverse(vals, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* if aligned, should be atomic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if ((ea & 0xf) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return do_stq(ea, vals[0], vals[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) err = write_mem(vals[IS_LE], ea, 8, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) err = write_mem(vals[IS_BE], ea + 8, 8, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) #endif /* __powerpc64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) const void *mem, bool rev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int size, read_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) const unsigned int *wp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) const unsigned short *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) const unsigned char *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) size = GETSIZE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) reg->d[0] = reg->d[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) switch (op->element_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* whole vector; lxv[x] or lxvl[l] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) memcpy(reg, mem, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (IS_LE && (op->vsx_flags & VSX_LDLEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) rev = !rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (rev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) do_byte_reverse(reg, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /* scalar loads, lxvd2x, lxvdsx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) read_size = (size >= 8) ? 8 : size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) i = IS_LE ? 8 : 8 - read_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) memcpy(®->b[i], mem, read_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (rev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) do_byte_reverse(®->b[i], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (size < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (op->type & SIGNEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* size == 4 is the only case here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) reg->d[IS_LE] = (signed int) reg->d[IS_LE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) } else if (op->vsx_flags & VSX_FPCONV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) conv_sp_to_dp(®->fp[1 + IS_LE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ®->dp[IS_LE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (size == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) unsigned long v = *(unsigned long *)(mem + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) reg->d[IS_BE] = !rev ? v : byterev_8(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) } else if (op->vsx_flags & VSX_SPLAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) reg->d[IS_BE] = reg->d[IS_LE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /* lxvw4x, lxvwsx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) wp = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) for (j = 0; j < size / 4; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) i = IS_LE ? 3 - j : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) reg->w[i] = !rev ? *wp++ : byterev_4(*wp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (op->vsx_flags & VSX_SPLAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) u32 val = reg->w[IS_LE ? 3 : 0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) for (; j < 4; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) i = IS_LE ? 3 - j : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) reg->w[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /* lxvh8x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) hp = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) for (j = 0; j < size / 2; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) i = IS_LE ? 7 - j : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) reg->h[i] = !rev ? *hp++ : byterev_2(*hp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* lxvb16x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) bp = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) for (j = 0; j < size; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) i = IS_LE ? 15 - j : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) reg->b[i] = *bp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) EXPORT_SYMBOL_GPL(emulate_vsx_load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) NOKPROBE_SYMBOL(emulate_vsx_load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) void *mem, bool rev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) int size, write_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) union vsx_reg buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) unsigned int *wp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) unsigned short *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) unsigned char *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) size = GETSIZE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) switch (op->element_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /* stxv, stxvx, stxvl, stxvll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (IS_LE && (op->vsx_flags & VSX_LDLEFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) rev = !rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (rev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* reverse 16 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) buf.d[0] = byterev_8(reg->d[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) buf.d[1] = byterev_8(reg->d[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) reg = &buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) memcpy(mem, reg, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* scalar stores, stxvd2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) write_size = (size >= 8) ? 8 : size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) i = IS_LE ? 8 : 8 - write_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (size < 8 && op->vsx_flags & VSX_FPCONV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) buf.d[0] = buf.d[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) conv_dp_to_sp(®->dp[IS_LE], &buf.fp[1 + IS_LE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) reg = &buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) memcpy(mem, ®->b[i], write_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) memcpy(mem + 8, ®->d[IS_BE], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (unlikely(rev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) do_byte_reverse(mem, write_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) do_byte_reverse(mem + 8, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* stxvw4x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) wp = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) for (j = 0; j < size / 4; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) i = IS_LE ? 3 - j : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) *wp++ = !rev ? reg->w[i] : byterev_4(reg->w[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) /* stxvh8x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) hp = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) for (j = 0; j < size / 2; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) i = IS_LE ? 7 - j : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) *hp++ = !rev ? reg->h[i] : byterev_2(reg->h[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /* stvxb16x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) bp = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) for (j = 0; j < size; ++j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) i = IS_LE ? 15 - j : j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) *bp++ = reg->b[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) EXPORT_SYMBOL_GPL(emulate_vsx_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) NOKPROBE_SYMBOL(emulate_vsx_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static nokprobe_inline int do_vsx_load(struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) unsigned long ea, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int reg = op->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u8 mem[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) union vsx_reg buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) int size = GETSIZE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) emulate_vsx_load(op, &buf, mem, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (reg < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* FP regs + extensions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (regs->msr & MSR_FP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) load_vsrn(reg, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) current->thread.fp_state.fpr[reg][0] = buf.d[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) current->thread.fp_state.fpr[reg][1] = buf.d[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (regs->msr & MSR_VEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) load_vsrn(reg, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) current->thread.vr_state.vr[reg - 32] = buf.v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static nokprobe_inline int do_vsx_store(struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) unsigned long ea, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) bool cross_endian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int reg = op->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) u8 mem[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) union vsx_reg buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) int size = GETSIZE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (!address_ok(regs, ea, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (reg < 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* FP regs + extensions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (regs->msr & MSR_FP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) store_vsrn(reg, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) buf.d[0] = current->thread.fp_state.fpr[reg][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) buf.d[1] = current->thread.fp_state.fpr[reg][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (regs->msr & MSR_VEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) store_vsrn(reg, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) buf.v = current->thread.vr_state.vr[reg - 32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) emulate_vsx_store(op, &buf, mem, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return copy_mem_out(mem, ea, size, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) #endif /* CONFIG_VSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) int emulate_dcbz(unsigned long ea, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) unsigned long i, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) size = ppc64_caches.l1d.block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (!(regs->msr & MSR_64BIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ea &= 0xffffffffUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) size = L1_CACHE_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ea &= ~(size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (!address_ok(regs, ea, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) for (i = 0; i < size; i += sizeof(long)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) err = __put_user(0, (unsigned long __user *) (ea + i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) NOKPROBE_SYMBOL(emulate_dcbz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) #define __put_user_asmx(x, addr, err, op, cr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) __asm__ __volatile__( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ".machine push\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) ".machine power8\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) "1: " op " %2,0,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) ".machine pop\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) " mfcr %1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) "2:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ".section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) "3: li %0,%4\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) " b 2b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ".previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) EX_TABLE(1b, 3b) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) : "=r" (err), "=r" (cr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) #define __get_user_asmx(x, addr, err, op) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) __asm__ __volatile__( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ".machine push\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ".machine power8\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) "1: "op" %1,0,%2\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ".machine pop\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) "2:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ".section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) "3: li %0,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) " b 2b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ".previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) EX_TABLE(1b, 3b) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) : "=r" (err), "=r" (x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) : "r" (addr), "i" (-EFAULT), "0" (err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) #define __cacheop_user_asmx(addr, err, op) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) __asm__ __volatile__( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) "1: "op" 0,%1\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) "2:\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) ".section .fixup,\"ax\"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) "3: li %0,%3\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) " b 2b\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ".previous\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) EX_TABLE(1b, 3b) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) : "=r" (err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) : "r" (addr), "i" (-EFAULT), "0" (err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static nokprobe_inline void set_cr0(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct instruction_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) long val = op->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) op->type |= SETCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) op->ccval = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (!(regs->msr & MSR_64BIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) val = (int) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) op->ccval |= 0x80000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) else if (val > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) op->ccval |= 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) op->ccval |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static nokprobe_inline void set_ca32(struct instruction_op *op, bool val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (cpu_has_feature(CPU_FTR_ARCH_300)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) op->xerval |= XER_CA32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) op->xerval &= ~XER_CA32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static nokprobe_inline void add_with_carry(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct instruction_op *op, int rd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) unsigned long val1, unsigned long val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) unsigned long carry_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) unsigned long val = val1 + val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (carry_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) ++val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) op->type = COMPUTE + SETREG + SETXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) op->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!(regs->msr & MSR_64BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) val = (unsigned int) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) val1 = (unsigned int) val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) op->xerval = regs->xer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (val < val1 || (carry_in && val == val1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) op->xerval |= XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) op->xerval &= ~XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) set_ca32(op, (unsigned int)val < (unsigned int)val1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) (carry_in && (unsigned int)val == (unsigned int)val1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static nokprobe_inline void do_cmp_signed(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) long v1, long v2, int crfld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) unsigned int crval, shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) op->type = COMPUTE + SETCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) crval = (regs->xer >> 31) & 1; /* get SO bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (v1 < v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) crval |= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) else if (v1 > v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) crval |= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) crval |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) shift = (7 - crfld) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) op->ccval = (regs->ccr & ~(0xf << shift)) | (crval << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static nokprobe_inline void do_cmp_unsigned(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) unsigned long v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) unsigned long v2, int crfld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) unsigned int crval, shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) op->type = COMPUTE + SETCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) crval = (regs->xer >> 31) & 1; /* get SO bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (v1 < v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) crval |= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) else if (v1 > v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) crval |= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) crval |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) shift = (7 - crfld) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) op->ccval = (regs->ccr & ~(0xf << shift)) | (crval << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static nokprobe_inline void do_cmpb(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) unsigned long v1, unsigned long v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) unsigned long long out_val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) out_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) mask = 0xffUL << (i * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if ((v1 & mask) == (v2 & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) out_val |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) op->val = out_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * The size parameter is used to adjust the equivalent popcnt instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * popcntb = 8, popcntw = 32, popcntd = 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static nokprobe_inline void do_popcnt(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) unsigned long v1, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) unsigned long long out = v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) out -= (out >> 1) & 0x5555555555555555ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) out = (0x3333333333333333ULL & out) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) (0x3333333333333333ULL & (out >> 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) out = (out + (out >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (size == 8) { /* popcntb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) op->val = out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) out += out >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) out += out >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (size == 32) { /* popcntw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) op->val = out & 0x0000003f0000003fULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) out = (out + (out >> 32)) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) op->val = out; /* popcntd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static nokprobe_inline void do_bpermd(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) unsigned long v1, unsigned long v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) unsigned char perm, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) perm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) idx = (v1 >> (i * 8)) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (idx < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (v2 & PPC_BIT(idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) perm |= 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) op->val = perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) #endif /* CONFIG_PPC64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * The size parameter adjusts the equivalent prty instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * prtyw = 32, prtyd = 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static nokprobe_inline void do_prty(const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct instruction_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) unsigned long v, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) unsigned long long res = v ^ (v >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) res ^= res >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (size == 32) { /* prtyw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) op->val = res & 0x0000000100000001ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) res ^= res >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) op->val = res & 1; /*prtyd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) static nokprobe_inline int trap_compare(long v1, long v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (v1 < v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ret |= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) else if (v1 > v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) ret |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ret |= 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if ((unsigned long)v1 < (unsigned long)v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ret |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) else if ((unsigned long)v1 > (unsigned long)v2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ret |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * Elements of 32-bit rotate and mask instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) #define MASK32(mb, me) ((0xffffffffUL >> (mb)) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) ((signed long)-0x80000000L >> (me)) + ((me) >= (mb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) #define MASK64_L(mb) (~0UL >> (mb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) #define MASK64_R(me) ((signed long)-0x8000000000000000L >> (me))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) #define MASK64(mb, me) (MASK64_L(mb) + MASK64_R(me) + ((me) >= (mb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) #define DATA32(x) (((x) & 0xffffffffUL) | (((x) & 0xffffffffUL) << 32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) #define DATA32(x) (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) #define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long) - (n)))) : (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) * Decode an instruction, and return information about it in *op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * without changing *regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * Integer arithmetic and logical instructions, branches, and barrier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * instructions can be emulated just using the information in *op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * Return value is 1 if the instruction can be emulated just by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * updating *regs with the information in *op, -1 if we need the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * GPRs but *regs doesn't contain the full register set, or 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct ppc_inst instr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) unsigned int suffixopcode, prefixtype, prefix_r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) unsigned int opcode, ra, rb, rc, rd, spr, u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) unsigned long int imm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) unsigned long int val, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) unsigned int mb, me, sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) unsigned int word, suffix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) long ival;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) word = ppc_inst_val(instr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) suffix = ppc_inst_suffix(instr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) op->type = COMPUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) opcode = ppc_inst_primary_opcode(instr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) case 16: /* bc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) op->type = BRANCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) imm = (signed short)(word & 0xfffc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if ((word & 2) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) imm += regs->nip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) op->val = truncate_if_32bit(regs->msr, imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (word & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) op->type |= SETLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (branch_taken(word, regs, op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) op->type |= BRTAKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) case 17: /* sc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if ((word & 0xfe2) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) op->type = SYSCALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) (word & 0xfe3) == 1) { /* scv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) op->type = SYSCALL_VECTORED_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) op->type = UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) case 18: /* b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) op->type = BRANCH | BRTAKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) imm = word & 0x03fffffc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (imm & 0x02000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) imm -= 0x04000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if ((word & 2) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) imm += regs->nip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) op->val = truncate_if_32bit(regs->msr, imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (word & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) op->type |= SETLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) case 19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) switch ((word >> 1) & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) case 0: /* mcrf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) op->type = COMPUTE + SETCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) rd = 7 - ((word >> 23) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ra = 7 - ((word >> 18) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) rd *= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) ra *= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) val = (regs->ccr >> ra) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) op->ccval = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) case 16: /* bclr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) case 528: /* bcctr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) op->type = BRANCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) imm = (word & 0x400)? regs->ctr: regs->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) op->val = truncate_if_32bit(regs->msr, imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (word & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) op->type |= SETLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (branch_taken(word, regs, op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) op->type |= BRTAKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) case 18: /* rfid, scary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (regs->msr & MSR_PR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) goto priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) op->type = RFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) case 150: /* isync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) op->type = BARRIER | BARRIER_ISYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) case 33: /* crnor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) case 129: /* crandc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) case 193: /* crxor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) case 225: /* crnand */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) case 257: /* crand */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case 289: /* creqv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) case 417: /* crorc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) case 449: /* cror */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) op->type = COMPUTE + SETCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) ra = (word >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) rb = (word >> 11) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) rd = (word >> 21) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) ra = (regs->ccr >> (31 - ra)) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) rb = (regs->ccr >> (31 - rb)) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) val = (word >> (6 + ra * 2 + rb)) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) op->ccval = (regs->ccr & ~(1UL << (31 - rd))) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) (val << (31 - rd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) case 31:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) switch ((word >> 1) & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) case 598: /* sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) op->type = BARRIER + BARRIER_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) switch ((word >> 21) & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) case 1: /* lwsync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) op->type = BARRIER + BARRIER_LWSYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case 2: /* ptesync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) op->type = BARRIER + BARRIER_PTESYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) case 854: /* eieio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) op->type = BARRIER + BARRIER_EIEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) /* Following cases refer to regs->gpr[], so we need all regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (!FULL_REGS(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) rd = (word >> 21) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) ra = (word >> 16) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) rb = (word >> 11) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) rc = (word >> 6) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (!cpu_has_feature(CPU_FTR_ARCH_31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) prefix_r = GET_PREFIX_R(word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) ra = GET_PREFIX_RA(suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) rd = (suffix >> 21) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) op->val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) suffixopcode = get_op(suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) prefixtype = (word >> 24) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) switch (prefixtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (prefix_r && ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) switch (suffixopcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) case 14: /* paddi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) op->type = COMPUTE | PREFIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) op->val = mlsd_8lsd_ea(word, suffix, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) case 2: /* tdi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (rd & trap_compare(regs->gpr[ra], (short) word))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) goto trap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) case 3: /* twi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (rd & trap_compare((int)regs->gpr[ra], (short) word))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) goto trap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) * There are very many instructions with this primary opcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) * introduced in the ISA as early as v2.03. However, the ones
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) * we currently emulate were all introduced with ISA 3.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) switch (word & 0x3f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) case 48: /* maddhd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) asm volatile(PPC_MADDHD(%0, %1, %2, %3) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) "=r" (op->val) : "r" (regs->gpr[ra]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) "r" (regs->gpr[rb]), "r" (regs->gpr[rc]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) case 49: /* maddhdu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) asm volatile(PPC_MADDHDU(%0, %1, %2, %3) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) "=r" (op->val) : "r" (regs->gpr[ra]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) "r" (regs->gpr[rb]), "r" (regs->gpr[rc]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) case 51: /* maddld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) asm volatile(PPC_MADDLD(%0, %1, %2, %3) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) "=r" (op->val) : "r" (regs->gpr[ra]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) "r" (regs->gpr[rb]), "r" (regs->gpr[rc]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * There are other instructions from ISA 3.0 with the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * primary opcode which do not have emulation support yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) case 7: /* mulli */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) op->val = regs->gpr[ra] * (short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) case 8: /* subfic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) imm = (short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) case 10: /* cmpli */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) imm = (unsigned short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) val = regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if ((rd & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) val = (unsigned int) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) do_cmp_unsigned(regs, op, val, imm, rd >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) case 11: /* cmpi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) imm = (short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) val = regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if ((rd & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) val = (int) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) do_cmp_signed(regs, op, val, imm, rd >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) case 12: /* addic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) imm = (short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) case 13: /* addic. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) imm = (short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) set_cr0(regs, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) case 14: /* addi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) imm = (short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) imm += regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) op->val = imm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) case 15: /* addis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) imm = ((short) word) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) if (ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) imm += regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) op->val = imm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) case 19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (((word >> 1) & 0x1f) == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /* addpcis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) imm = (short) (word & 0xffc1); /* d0 + d2 fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) imm |= (word >> 15) & 0x3e; /* d1 field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) op->val = regs->nip + (imm << 16) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) op->type = UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) case 20: /* rlwimi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) mb = (word >> 6) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) me = (word >> 1) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) val = DATA32(regs->gpr[rd]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) imm = MASK32(mb, me);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) case 21: /* rlwinm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) mb = (word >> 6) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) me = (word >> 1) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) val = DATA32(regs->gpr[rd]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) op->val = ROTATE(val, rb) & MASK32(mb, me);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) case 23: /* rlwnm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) mb = (word >> 6) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) me = (word >> 1) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) rb = regs->gpr[rb] & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) val = DATA32(regs->gpr[rd]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) op->val = ROTATE(val, rb) & MASK32(mb, me);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) case 24: /* ori */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) op->val = regs->gpr[rd] | (unsigned short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) case 25: /* oris */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) imm = (unsigned short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) op->val = regs->gpr[rd] | (imm << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) case 26: /* xori */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) op->val = regs->gpr[rd] ^ (unsigned short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) case 27: /* xoris */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) imm = (unsigned short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) op->val = regs->gpr[rd] ^ (imm << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) case 28: /* andi. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) op->val = regs->gpr[rd] & (unsigned short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) set_cr0(regs, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) case 29: /* andis. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) imm = (unsigned short) word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) op->val = regs->gpr[rd] & (imm << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) set_cr0(regs, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) case 30: /* rld* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) mb = ((word >> 6) & 0x1f) | (word & 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) if ((word & 0x10) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) sh = rb | ((word & 2) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) val = ROTATE(val, sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) switch ((word >> 2) & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) case 0: /* rldicl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) val &= MASK64_L(mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) case 1: /* rldicr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) val &= MASK64_R(mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) case 2: /* rldic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) val &= MASK64(mb, 63 - sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) case 3: /* rldimi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) imm = MASK64(mb, 63 - sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) val = (regs->gpr[ra] & ~imm) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) (val & imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) op->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) sh = regs->gpr[rb] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) val = ROTATE(val, sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) switch ((word >> 1) & 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case 0: /* rldcl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) op->val = val & MASK64_L(mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) case 1: /* rldcr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) op->val = val & MASK64_R(mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) op->type = UNKNOWN; /* illegal instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) case 31:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /* isel occupies 32 minor opcodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (((word >> 1) & 0x1f) == 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) mb = (word >> 6) & 0x1f; /* bc field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) val = (regs->ccr >> (31 - mb)) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) val2 = (ra) ? regs->gpr[ra] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) op->val = (val) ? val2 : regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) switch ((word >> 1) & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) case 4: /* tw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (rd == 0x1f ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) (rd & trap_compare((int)regs->gpr[ra],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) (int)regs->gpr[rb])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) goto trap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) case 68: /* td */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (rd & trap_compare(regs->gpr[ra], regs->gpr[rb]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) goto trap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) case 83: /* mfmsr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) if (regs->msr & MSR_PR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) goto priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) op->type = MFMSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) case 146: /* mtmsr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (regs->msr & MSR_PR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) goto priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) op->type = MTMSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) op->val = 0xffffffff & ~(MSR_ME | MSR_LE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) case 178: /* mtmsrd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (regs->msr & MSR_PR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) goto priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) op->type = MTMSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* only MSR_EE and MSR_RI get changed if bit 15 set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) imm = (word & 0x10000)? 0x8002: 0xefffffffffffeffeUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) op->val = imm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) case 19: /* mfcr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) imm = 0xffffffffUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if ((word >> 20) & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) imm = 0xf0000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) for (sh = 0; sh < 8; ++sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (word & (0x80000 >> sh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) imm >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) op->val = regs->ccr & imm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) case 144: /* mtcrf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) op->type = COMPUTE + SETCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) imm = 0xf0000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) op->ccval = regs->ccr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) for (sh = 0; sh < 8; ++sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (word & (0x80000 >> sh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) op->ccval = (op->ccval & ~imm) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) (val & imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) imm >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) case 339: /* mfspr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) op->type = MFSPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) op->spr = spr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) if (spr == SPRN_XER || spr == SPRN_LR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) spr == SPRN_CTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) case 467: /* mtspr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) op->type = MTSPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) op->val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) op->spr = spr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (spr == SPRN_XER || spr == SPRN_LR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) spr == SPRN_CTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) * Compare instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) case 0: /* cmp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) val = regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) val2 = regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) if ((rd & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /* word (32-bit) compare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) val = (int) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) val2 = (int) val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) do_cmp_signed(regs, op, val, val2, rd >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) case 32: /* cmpl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) val = regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) val2 = regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if ((rd & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) /* word (32-bit) compare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) val = (unsigned int) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) val2 = (unsigned int) val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) do_cmp_unsigned(regs, op, val, val2, rd >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) case 508: /* cmpb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) do_cmpb(regs, op, regs->gpr[rd], regs->gpr[rb]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * Arithmetic instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) case 8: /* subfc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) add_with_carry(regs, op, rd, ~regs->gpr[ra],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) regs->gpr[rb], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) case 9: /* mulhdu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) asm("mulhdu %0,%1,%2" : "=r" (op->val) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) case 10: /* addc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) add_with_carry(regs, op, rd, regs->gpr[ra],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) regs->gpr[rb], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) case 11: /* mulhwu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) asm("mulhwu %0,%1,%2" : "=r" (op->val) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) case 40: /* subf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) op->val = regs->gpr[rb] - regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) case 73: /* mulhd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) asm("mulhd %0,%1,%2" : "=r" (op->val) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) case 75: /* mulhw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) asm("mulhw %0,%1,%2" : "=r" (op->val) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) case 104: /* neg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) op->val = -regs->gpr[ra];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) case 136: /* subfe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) add_with_carry(regs, op, rd, ~regs->gpr[ra],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) regs->gpr[rb], regs->xer & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) case 138: /* adde */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) add_with_carry(regs, op, rd, regs->gpr[ra],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) regs->gpr[rb], regs->xer & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) case 200: /* subfze */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) add_with_carry(regs, op, rd, ~regs->gpr[ra], 0L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) regs->xer & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) case 202: /* addze */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) add_with_carry(regs, op, rd, regs->gpr[ra], 0L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) regs->xer & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) case 232: /* subfme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) add_with_carry(regs, op, rd, ~regs->gpr[ra], -1L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) regs->xer & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) case 233: /* mulld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) op->val = regs->gpr[ra] * regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) case 234: /* addme */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) add_with_carry(regs, op, rd, regs->gpr[ra], -1L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) regs->xer & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) case 235: /* mullw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) op->val = (long)(int) regs->gpr[ra] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) (int) regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) case 265: /* modud */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) op->val = regs->gpr[ra] % regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) case 266: /* add */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) op->val = regs->gpr[ra] + regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) case 267: /* moduw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) op->val = (unsigned int) regs->gpr[ra] %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) (unsigned int) regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) case 457: /* divdu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) op->val = regs->gpr[ra] / regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) case 459: /* divwu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) op->val = (unsigned int) regs->gpr[ra] /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) (unsigned int) regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) case 489: /* divd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) op->val = (long int) regs->gpr[ra] /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) (long int) regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) case 491: /* divw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) op->val = (int) regs->gpr[ra] /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) (int) regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) case 425: /* divde[.] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) asm volatile(PPC_DIVDE(%0, %1, %2) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) "=r" (op->val) : "r" (regs->gpr[ra]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) "r" (regs->gpr[rb]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) case 393: /* divdeu[.] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) asm volatile(PPC_DIVDEU(%0, %1, %2) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) "=r" (op->val) : "r" (regs->gpr[ra]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) "r" (regs->gpr[rb]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) goto arith_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) case 755: /* darn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) switch (ra & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) /* 32-bit conditioned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) asm volatile(PPC_DARN(%0, 0) : "=r" (op->val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) /* 64-bit conditioned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) asm volatile(PPC_DARN(%0, 1) : "=r" (op->val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) /* 64-bit raw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) asm volatile(PPC_DARN(%0, 2) : "=r" (op->val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) case 777: /* modsd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) op->val = (long int) regs->gpr[ra] %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) (long int) regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) case 779: /* modsw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) op->val = (int) regs->gpr[ra] %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) (int) regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) goto compute_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) * Logical instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) case 26: /* cntlzw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) val = (unsigned int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) op->val = ( val ? __builtin_clz(val) : 32 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) case 58: /* cntlzd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) op->val = ( val ? __builtin_clzl(val) : 64 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) case 28: /* and */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) op->val = regs->gpr[rd] & regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) case 60: /* andc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) op->val = regs->gpr[rd] & ~regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) case 122: /* popcntb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) do_popcnt(regs, op, regs->gpr[rd], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) case 124: /* nor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) op->val = ~(regs->gpr[rd] | regs->gpr[rb]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) case 154: /* prtyw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) do_prty(regs, op, regs->gpr[rd], 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) case 186: /* prtyd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) do_prty(regs, op, regs->gpr[rd], 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) case 252: /* bpermd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) do_bpermd(regs, op, regs->gpr[rd], regs->gpr[rb]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) case 284: /* xor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) op->val = ~(regs->gpr[rd] ^ regs->gpr[rb]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) case 316: /* xor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) op->val = regs->gpr[rd] ^ regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) case 378: /* popcntw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) do_popcnt(regs, op, regs->gpr[rd], 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) case 412: /* orc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) op->val = regs->gpr[rd] | ~regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) case 444: /* or */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) op->val = regs->gpr[rd] | regs->gpr[rb];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) case 476: /* nand */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) op->val = ~(regs->gpr[rd] & regs->gpr[rb]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) case 506: /* popcntd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) do_popcnt(regs, op, regs->gpr[rd], 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) goto logical_done_nocc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) case 538: /* cnttzw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) val = (unsigned int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) op->val = (val ? __builtin_ctz(val) : 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) case 570: /* cnttzd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) op->val = (val ? __builtin_ctzl(val) : 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) case 922: /* extsh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) op->val = (signed short) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) case 954: /* extsb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) op->val = (signed char) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) case 986: /* extsw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) op->val = (signed int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) * Shift instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) case 24: /* slw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) sh = regs->gpr[rb] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) if (sh < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) op->val = (regs->gpr[rd] << sh) & 0xffffffffUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) op->val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) case 536: /* srw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) sh = regs->gpr[rb] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) if (sh < 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) op->val = (regs->gpr[rd] & 0xffffffffUL) >> sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) op->val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) case 792: /* sraw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) op->type = COMPUTE + SETREG + SETXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) sh = regs->gpr[rb] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) ival = (signed int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) op->val = ival >> (sh < 32 ? sh : 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) op->xerval = regs->xer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) op->xerval |= XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) op->xerval &= ~XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) set_ca32(op, op->xerval & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) case 824: /* srawi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) op->type = COMPUTE + SETREG + SETXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) sh = rb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) ival = (signed int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) op->val = ival >> sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) op->xerval = regs->xer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) op->xerval |= XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) op->xerval &= ~XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) set_ca32(op, op->xerval & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) case 27: /* sld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) sh = regs->gpr[rb] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) if (sh < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) op->val = regs->gpr[rd] << sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) op->val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) case 539: /* srd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) sh = regs->gpr[rb] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) if (sh < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) op->val = regs->gpr[rd] >> sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) op->val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) case 794: /* srad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) op->type = COMPUTE + SETREG + SETXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) sh = regs->gpr[rb] & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) ival = (signed long int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) op->val = ival >> (sh < 64 ? sh : 63);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) op->xerval = regs->xer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) op->xerval |= XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) op->xerval &= ~XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) set_ca32(op, op->xerval & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) case 826: /* sradi with sh_5 = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) case 827: /* sradi with sh_5 = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) op->type = COMPUTE + SETREG + SETXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) sh = rb | ((word & 2) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) ival = (signed long int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) op->val = ival >> sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) op->xerval = regs->xer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) op->xerval |= XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) op->xerval &= ~XER_CA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) set_ca32(op, op->xerval & XER_CA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) case 890: /* extswsli with sh_5 = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) case 891: /* extswsli with sh_5 = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) op->type = COMPUTE + SETREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) sh = rb | ((word & 2) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) val = (signed int) regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) if (sh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) op->val = ROTATE(val, sh) & MASK64(0, 63 - sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) op->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) goto logical_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) #endif /* __powerpc64__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) * Cache instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) case 54: /* dcbst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) op->type = MKOP(CACHEOP, DCBST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) op->ea = xform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) case 86: /* dcbf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) op->type = MKOP(CACHEOP, DCBF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) op->ea = xform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) case 246: /* dcbtst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) op->type = MKOP(CACHEOP, DCBTST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) op->ea = xform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) case 278: /* dcbt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) op->type = MKOP(CACHEOP, DCBTST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) op->ea = xform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) case 982: /* icbi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) op->type = MKOP(CACHEOP, ICBI, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) op->ea = xform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) case 1014: /* dcbz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) op->type = MKOP(CACHEOP, DCBZ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) op->ea = xform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * Loads and stores.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) op->type = UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) op->update_reg = ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) op->val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) u = (word >> 20) & UPDATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) op->vsx_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) case 31:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) u = word & UPDATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) op->ea = xform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) switch ((word >> 1) & 0x3ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) case 20: /* lwarx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) op->type = MKOP(LARX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) case 150: /* stwcx. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) op->type = MKOP(STCX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) case 84: /* ldarx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) op->type = MKOP(LARX, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) case 214: /* stdcx. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) op->type = MKOP(STCX, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) case 52: /* lbarx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) op->type = MKOP(LARX, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) case 694: /* stbcx. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) op->type = MKOP(STCX, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) case 116: /* lharx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) op->type = MKOP(LARX, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) case 726: /* sthcx. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) op->type = MKOP(STCX, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) case 276: /* lqarx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if (!((rd & 1) || rd == ra || rd == rb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) op->type = MKOP(LARX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) case 182: /* stqcx. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) if (!(rd & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) op->type = MKOP(STCX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) case 23: /* lwzx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) case 55: /* lwzux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) op->type = MKOP(LOAD, u, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) case 87: /* lbzx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) case 119: /* lbzux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) op->type = MKOP(LOAD, u, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) #ifdef CONFIG_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) * Note: for the load/store vector element instructions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) * bits of the EA say which field of the VMX register to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) case 7: /* lvebx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) op->type = MKOP(LOAD_VMX, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) op->element_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) case 39: /* lvehx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) op->type = MKOP(LOAD_VMX, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) op->element_size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) case 71: /* lvewx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) op->type = MKOP(LOAD_VMX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) op->element_size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) case 103: /* lvx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) case 359: /* lvxl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) op->type = MKOP(LOAD_VMX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) case 135: /* stvebx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) op->type = MKOP(STORE_VMX, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) op->element_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) case 167: /* stvehx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) op->type = MKOP(STORE_VMX, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) op->element_size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) case 199: /* stvewx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) op->type = MKOP(STORE_VMX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) op->element_size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) case 231: /* stvx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) case 487: /* stvxl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) op->type = MKOP(STORE_VMX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) #endif /* CONFIG_ALTIVEC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) case 21: /* ldx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) case 53: /* ldux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) op->type = MKOP(LOAD, u, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) case 149: /* stdx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) case 181: /* stdux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) op->type = MKOP(STORE, u, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) case 151: /* stwx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) case 183: /* stwux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) op->type = MKOP(STORE, u, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) case 215: /* stbx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) case 247: /* stbux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) op->type = MKOP(STORE, u, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) case 279: /* lhzx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) case 311: /* lhzux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) op->type = MKOP(LOAD, u, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) case 341: /* lwax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) case 373: /* lwaux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) op->type = MKOP(LOAD, SIGNEXT | u, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) case 343: /* lhax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) case 375: /* lhaux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) op->type = MKOP(LOAD, SIGNEXT | u, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) case 407: /* sthx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) case 439: /* sthux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) op->type = MKOP(STORE, u, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) case 532: /* ldbrx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) op->type = MKOP(LOAD, BYTEREV, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) case 533: /* lswx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) op->type = MKOP(LOAD_MULTI, 0, regs->xer & 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) case 534: /* lwbrx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) op->type = MKOP(LOAD, BYTEREV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) case 597: /* lswi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (rb == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) rb = 32; /* # bytes to load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) op->type = MKOP(LOAD_MULTI, 0, rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) op->ea = ra ? regs->gpr[ra] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) #ifdef CONFIG_PPC_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) case 535: /* lfsx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) case 567: /* lfsux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) op->type = MKOP(LOAD_FP, u | FPCONV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) case 599: /* lfdx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) case 631: /* lfdux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) op->type = MKOP(LOAD_FP, u, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) case 663: /* stfsx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) case 695: /* stfsux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) op->type = MKOP(STORE_FP, u | FPCONV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) case 727: /* stfdx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) case 759: /* stfdux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) op->type = MKOP(STORE_FP, u, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) case 791: /* lfdpx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) op->type = MKOP(LOAD_FP, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) case 855: /* lfiwax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) op->type = MKOP(LOAD_FP, SIGNEXT, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) case 887: /* lfiwzx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) op->type = MKOP(LOAD_FP, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) case 919: /* stfdpx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) op->type = MKOP(STORE_FP, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) case 983: /* stfiwx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) op->type = MKOP(STORE_FP, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) #endif /* __powerpc64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) #endif /* CONFIG_PPC_FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) case 660: /* stdbrx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) op->type = MKOP(STORE, BYTEREV, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) op->val = byterev_8(regs->gpr[rd]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) case 661: /* stswx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) op->type = MKOP(STORE_MULTI, 0, regs->xer & 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) case 662: /* stwbrx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) op->type = MKOP(STORE, BYTEREV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) op->val = byterev_4(regs->gpr[rd]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) case 725: /* stswi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) if (rb == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) rb = 32; /* # bytes to store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) op->type = MKOP(STORE_MULTI, 0, rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) op->ea = ra ? regs->gpr[ra] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) case 790: /* lhbrx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) op->type = MKOP(LOAD, BYTEREV, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) case 918: /* sthbrx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) op->type = MKOP(STORE, BYTEREV, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) op->val = byterev_2(regs->gpr[rd]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) case 12: /* lxsiwzx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) op->type = MKOP(LOAD_VSX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) case 76: /* lxsiwax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) op->type = MKOP(LOAD_VSX, SIGNEXT, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) case 140: /* stxsiwx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) op->type = MKOP(STORE_VSX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) case 268: /* lxvx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) op->type = MKOP(LOAD_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) case 269: /* lxvl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) case 301: { /* lxvll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) int nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) op->ea = ra ? regs->gpr[ra] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) nb = regs->gpr[rb] & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) if (nb > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) nb = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) op->type = MKOP(LOAD_VSX, 0, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) case 332: /* lxvdsx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) op->type = MKOP(LOAD_VSX, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) op->vsx_flags = VSX_SPLAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) case 364: /* lxvwsx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) op->type = MKOP(LOAD_VSX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) op->element_size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) case 396: /* stxvx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) op->type = MKOP(STORE_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) case 397: /* stxvl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) case 429: { /* stxvll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) int nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) op->ea = ra ? regs->gpr[ra] : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) nb = regs->gpr[rb] & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (nb > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) nb = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) op->type = MKOP(STORE_VSX, 0, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) case 524: /* lxsspx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) op->type = MKOP(LOAD_VSX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) op->vsx_flags = VSX_FPCONV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) case 588: /* lxsdx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) op->type = MKOP(LOAD_VSX, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) case 652: /* stxsspx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) op->type = MKOP(STORE_VSX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) op->vsx_flags = VSX_FPCONV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) case 716: /* stxsdx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) op->type = MKOP(STORE_VSX, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) case 780: /* lxvw4x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) op->type = MKOP(LOAD_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) op->element_size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) case 781: /* lxsibzx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) op->type = MKOP(LOAD_VSX, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) case 812: /* lxvh8x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) op->type = MKOP(LOAD_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) op->element_size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) case 813: /* lxsihzx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) op->type = MKOP(LOAD_VSX, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) case 844: /* lxvd2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) op->type = MKOP(LOAD_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) case 876: /* lxvb16x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) op->type = MKOP(LOAD_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) op->element_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) case 908: /* stxvw4x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) op->type = MKOP(STORE_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) op->element_size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) case 909: /* stxsibx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) op->type = MKOP(STORE_VSX, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) case 940: /* stxvh8x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) op->type = MKOP(STORE_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) op->element_size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) case 941: /* stxsihx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) op->type = MKOP(STORE_VSX, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) case 972: /* stxvd2x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) op->type = MKOP(STORE_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) case 1004: /* stxvb16x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) op->reg = rd | ((word & 1) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) op->type = MKOP(STORE_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) op->element_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) #endif /* CONFIG_VSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) case 32: /* lwz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) case 33: /* lwzu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) op->type = MKOP(LOAD, u, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) case 34: /* lbz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) case 35: /* lbzu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) op->type = MKOP(LOAD, u, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) case 36: /* stw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) case 37: /* stwu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) op->type = MKOP(STORE, u, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) case 38: /* stb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) case 39: /* stbu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) op->type = MKOP(STORE, u, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) case 40: /* lhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) case 41: /* lhzu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) op->type = MKOP(LOAD, u, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) case 42: /* lha */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) case 43: /* lhau */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) op->type = MKOP(LOAD, SIGNEXT | u, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) case 44: /* sth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) case 45: /* sthu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) op->type = MKOP(STORE, u, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) case 46: /* lmw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) if (ra >= rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) break; /* invalid form, ra in range to load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) case 47: /* stmw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) #ifdef CONFIG_PPC_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) case 48: /* lfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) case 49: /* lfsu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) op->type = MKOP(LOAD_FP, u | FPCONV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) case 50: /* lfd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) case 51: /* lfdu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) op->type = MKOP(LOAD_FP, u, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) case 52: /* stfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) case 53: /* stfsu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) op->type = MKOP(STORE_FP, u | FPCONV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) case 54: /* stfd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) case 55: /* stfdu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) op->type = MKOP(STORE_FP, u, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) op->ea = dform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) case 56: /* lq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) if (!((rd & 1) || (rd == ra)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) op->type = MKOP(LOAD, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) op->ea = dqform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) case 57: /* lfdp, lxsd, lxssp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) op->ea = dsform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) switch (word & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) case 0: /* lfdp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) if (rd & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) break; /* reg must be even */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) op->type = MKOP(LOAD_FP, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) case 2: /* lxsd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) op->type = MKOP(LOAD_VSX, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) case 3: /* lxssp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) op->type = MKOP(LOAD_VSX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) #endif /* CONFIG_VSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) case 58: /* ld[u], lwa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) op->ea = dsform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) switch (word & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) case 0: /* ld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) op->type = MKOP(LOAD, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) case 1: /* ldu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) op->type = MKOP(LOAD, UPDATE, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) case 2: /* lwa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) op->type = MKOP(LOAD, SIGNEXT, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) case 61: /* stfdp, lxv, stxsd, stxssp, stxv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) switch (word & 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) case 0: /* stfdp with LSB of DS field = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) case 4: /* stfdp with LSB of DS field = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) op->ea = dsform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) op->type = MKOP(STORE_FP, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) case 1: /* lxv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) op->ea = dqform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) if (word & 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) op->type = MKOP(LOAD_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) case 2: /* stxsd with LSB of DS field = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) case 6: /* stxsd with LSB of DS field = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) op->ea = dsform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) op->type = MKOP(STORE_VSX, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) case 3: /* stxssp with LSB of DS field = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) case 7: /* stxssp with LSB of DS field = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) op->ea = dsform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) op->type = MKOP(STORE_VSX, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) case 5: /* stxv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if (!cpu_has_feature(CPU_FTR_ARCH_300))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) op->ea = dqform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) if (word & 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) op->type = MKOP(STORE_VSX, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) #endif /* CONFIG_VSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) case 62: /* std[u] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) op->ea = dsform_ea(word, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) switch (word & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) case 0: /* std */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) op->type = MKOP(STORE, 0, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) case 1: /* stdu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) op->type = MKOP(STORE, UPDATE, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) case 2: /* stq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) if (!(rd & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) op->type = MKOP(STORE, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) case 1: /* Prefixed instructions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) if (!cpu_has_feature(CPU_FTR_ARCH_31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) prefix_r = GET_PREFIX_R(word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) ra = GET_PREFIX_RA(suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) op->update_reg = ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) rd = (suffix >> 21) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) op->val = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) suffixopcode = get_op(suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) prefixtype = (word >> 24) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) switch (prefixtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) case 0: /* Type 00 Eight-Byte Load/Store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) if (prefix_r && ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) op->ea = mlsd_8lsd_ea(word, suffix, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) switch (suffixopcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) case 41: /* plwa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) case 42: /* plxsd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) op->type = MKOP(LOAD_VSX, PREFIXED, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) case 43: /* plxssp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) op->type = MKOP(LOAD_VSX, PREFIXED, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) case 46: /* pstxsd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) op->type = MKOP(STORE_VSX, PREFIXED, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) case 47: /* pstxssp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) op->type = MKOP(STORE_VSX, PREFIXED, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) op->element_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) case 51: /* plxv1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) op->reg += 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) case 50: /* plxv0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) op->type = MKOP(LOAD_VSX, PREFIXED, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) case 55: /* pstxv1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) op->reg = rd + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) case 54: /* pstxv0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) op->type = MKOP(STORE_VSX, PREFIXED, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) op->element_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) op->vsx_flags = VSX_CHECK_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) #endif /* CONFIG_VSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) case 56: /* plq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) op->type = MKOP(LOAD, PREFIXED, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) case 57: /* pld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) op->type = MKOP(LOAD, PREFIXED, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) case 60: /* pstq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) op->type = MKOP(STORE, PREFIXED, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) case 61: /* pstd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) op->type = MKOP(STORE, PREFIXED, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) case 1: /* Type 01 Eight-Byte Register-to-Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) case 2: /* Type 10 Modified Load/Store */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) if (prefix_r && ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) op->ea = mlsd_8lsd_ea(word, suffix, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) switch (suffixopcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) case 32: /* plwz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) op->type = MKOP(LOAD, PREFIXED, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) case 34: /* plbz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) op->type = MKOP(LOAD, PREFIXED, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) case 36: /* pstw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) op->type = MKOP(STORE, PREFIXED, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) case 38: /* pstb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) op->type = MKOP(STORE, PREFIXED, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) case 40: /* plhz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) op->type = MKOP(LOAD, PREFIXED, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) case 42: /* plha */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) case 44: /* psth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) op->type = MKOP(STORE, PREFIXED, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) case 48: /* plfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) op->type = MKOP(LOAD_FP, PREFIXED | FPCONV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) case 50: /* plfd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) op->type = MKOP(LOAD_FP, PREFIXED, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) case 52: /* pstfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) op->type = MKOP(STORE_FP, PREFIXED | FPCONV, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) case 54: /* pstfd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) op->type = MKOP(STORE_FP, PREFIXED, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) case 3: /* Type 11 Modified Register-to-Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) #endif /* __powerpc64__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (OP_IS_LOAD_STORE(op->type) && (op->type & UPDATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) switch (GETTYPE(op->type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) case LOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) if (ra == rd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) case STORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) case LOAD_FP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) case STORE_FP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) if (ra == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) goto unknown_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) if ((GETTYPE(op->type) == LOAD_VSX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) GETTYPE(op->type) == STORE_VSX) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) !cpu_has_feature(CPU_FTR_VSX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) #endif /* CONFIG_VSX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) unknown_opcode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) op->type = UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) logical_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) if (word & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) set_cr0(regs, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) logical_done_nocc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) op->reg = ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) op->type |= SETREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) arith_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) if (word & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) set_cr0(regs, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) compute_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) op->reg = rd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) op->type |= SETREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) priv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) op->type = INTERRUPT | 0x700;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) op->val = SRR1_PROGPRIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) trap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) op->type = INTERRUPT | 0x700;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) op->val = SRR1_PROGTRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) EXPORT_SYMBOL_GPL(analyse_instr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) NOKPROBE_SYMBOL(analyse_instr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) * For PPC32 we always use stwu with r1 to change the stack pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) * So this emulated store may corrupt the exception frame, now we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) * have to provide the exception frame trampoline, which is pushed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) * below the kprobed function stack. So we only update gpr[1] but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) * don't emulate the real store operation. We will do real store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) * operation safely in exception return code by checking this flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) static nokprobe_inline int handle_stack_update(unsigned long ea, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) #ifdef CONFIG_PPC32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) * Check if we will touch kernel stack overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) if (ea - STACK_INT_FRAME_SIZE <= current->thread.ksp_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) printk(KERN_CRIT "Can't kprobe this since kernel stack would overflow.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) #endif /* CONFIG_PPC32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) * Check if we already set since that means we'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) * lose the previous value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) WARN_ON(test_thread_flag(TIF_EMULATE_STACK_STORE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) set_thread_flag(TIF_EMULATE_STACK_STORE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) static nokprobe_inline void do_signext(unsigned long *valp, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) *valp = (signed short) *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) *valp = (signed int) *valp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) static nokprobe_inline void do_byterev(unsigned long *valp, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) *valp = byterev_2(*valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) *valp = byterev_4(*valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) *valp = byterev_8(*valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) * Emulate an instruction that can be executed just by updating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) * fields in *regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) void emulate_update_regs(struct pt_regs *regs, struct instruction_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) unsigned long next_pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) next_pc = truncate_if_32bit(regs->msr, regs->nip + GETLENGTH(op->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) switch (GETTYPE(op->type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) case COMPUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) if (op->type & SETREG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) regs->gpr[op->reg] = op->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) if (op->type & SETCC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) regs->ccr = op->ccval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) if (op->type & SETXER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) regs->xer = op->xerval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) case BRANCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) if (op->type & SETLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) regs->link = next_pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) if (op->type & BRTAKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) next_pc = op->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) if (op->type & DECCTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) --regs->ctr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) case BARRIER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) switch (op->type & BARRIER_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) case BARRIER_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) case BARRIER_ISYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) isync();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) case BARRIER_EIEIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) eieio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) case BARRIER_LWSYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) asm volatile("lwsync" : : : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) case BARRIER_PTESYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) asm volatile("ptesync" : : : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) case MFSPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) switch (op->spr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) case SPRN_XER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) regs->gpr[op->reg] = regs->xer & 0xffffffffUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) case SPRN_LR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) regs->gpr[op->reg] = regs->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) case SPRN_CTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) regs->gpr[op->reg] = regs->ctr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) case MTSPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) switch (op->spr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) case SPRN_XER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) regs->xer = op->val & 0xffffffffUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) case SPRN_LR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) regs->link = op->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) case SPRN_CTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) regs->ctr = op->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) regs->nip = next_pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) NOKPROBE_SYMBOL(emulate_update_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) * Emulate a previously-analysed load or store instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) * Return values are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) * 0 = instruction emulated successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) * -EFAULT = address out of range or access faulted (regs->dar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) * contains the faulting address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) * -EACCES = misaligned access, instruction requires alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) * -EINVAL = unknown operation in *op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) int err, size, type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) int i, rd, nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) unsigned int cr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) unsigned long ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) bool cross_endian;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) size = GETSIZE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) type = GETTYPE(op->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) cross_endian = (regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) ea = truncate_if_32bit(regs->msr, op->ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) case LARX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) if (ea & (size - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) return -EACCES; /* can't handle misaligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) if (!address_ok(regs, ea, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) __get_user_asmx(val, ea, err, "lbarx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) __get_user_asmx(val, ea, err, "lharx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) __get_user_asmx(val, ea, err, "lwarx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) __get_user_asmx(val, ea, err, "ldarx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) err = do_lqarx(ea, ®s->gpr[op->reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) if (size < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) regs->gpr[op->reg] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) case STCX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) if (ea & (size - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) return -EACCES; /* can't handle misaligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) if (!address_ok(regs, ea, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) __put_user_asmx(op->val, ea, err, "stbcx.", cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) __put_user_asmx(op->val, ea, err, "sthcx.", cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) __put_user_asmx(op->val, ea, err, "stwcx.", cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) __put_user_asmx(op->val, ea, err, "stdcx.", cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) err = do_stqcx(ea, regs->gpr[op->reg],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) regs->gpr[op->reg + 1], &cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) regs->ccr = (regs->ccr & 0x0fffffff) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) (cr & 0xe0000000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) ((regs->xer >> 3) & 0x10000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) case LOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) if (size == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) err = emulate_lq(regs, ea, op->reg, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) err = read_mem(®s->gpr[op->reg], ea, size, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) if (op->type & SIGNEXT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) do_signext(®s->gpr[op->reg], size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) if ((op->type & BYTEREV) == (cross_endian ? 0 : BYTEREV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) do_byterev(®s->gpr[op->reg], size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) #ifdef CONFIG_PPC_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) case LOAD_FP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) * If the instruction is in userspace, we can emulate it even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) * if the VMX state is not live, because we have the state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) * stored in the thread_struct. If the instruction is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) * the kernel, we must not touch the state in the thread_struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) err = do_fp_load(op, ea, regs, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) #ifdef CONFIG_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) case LOAD_VMX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) err = do_vec_load(op->reg, ea, size, regs, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) case LOAD_VSX: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) unsigned long msrbit = MSR_VSX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) * Some VSX instructions check the MSR_VEC bit rather than MSR_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) * when the target of the instruction is a vector register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) msrbit = MSR_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) err = do_vsx_load(op, ea, regs, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) case LOAD_MULTI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) if (!address_ok(regs, ea, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) rd = op->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) for (i = 0; i < size; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) unsigned int v32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) nb = size - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) if (nb > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) nb = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) err = copy_mem_in((u8 *) &v32, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) if (unlikely(cross_endian))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) v32 = byterev_4(v32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) regs->gpr[rd] = v32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) ea += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) /* reg number wraps from 31 to 0 for lsw[ix] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) rd = (rd + 1) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) case STORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) #ifdef __powerpc64__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) if (size == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) err = emulate_stq(regs, ea, op->reg, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) if ((op->type & UPDATE) && size == sizeof(long) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) op->reg == 1 && op->update_reg == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) !(regs->msr & MSR_PR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) ea >= regs->gpr[1] - STACK_INT_FRAME_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) err = handle_stack_update(ea, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) if (unlikely(cross_endian))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) do_byterev(&op->val, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) err = write_mem(op->val, ea, size, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) #ifdef CONFIG_PPC_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) case STORE_FP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) err = do_fp_store(op, ea, regs, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) #ifdef CONFIG_ALTIVEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) case STORE_VMX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) err = do_vec_store(op->reg, ea, size, regs, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) #ifdef CONFIG_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) case STORE_VSX: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) unsigned long msrbit = MSR_VSX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) * Some VSX instructions check the MSR_VEC bit rather than MSR_VSX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) * when the target of the instruction is a vector register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) msrbit = MSR_VEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) err = do_vsx_store(op, ea, regs, cross_endian);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) case STORE_MULTI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) if (!address_ok(regs, ea, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) rd = op->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) for (i = 0; i < size; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) unsigned int v32 = regs->gpr[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) nb = size - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) if (nb > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) nb = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) if (unlikely(cross_endian))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) v32 = byterev_4(v32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) err = copy_mem_out((u8 *) &v32, ea, nb, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) ea += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) /* reg number wraps from 31 to 0 for stsw[ix] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) rd = (rd + 1) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) if (op->type & UPDATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) regs->gpr[op->update_reg] = op->ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) NOKPROBE_SYMBOL(emulate_loadstore);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) * Emulate instructions that cause a transfer of control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) * loads and stores, and a few other instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) * Returns 1 if the step was emulated, 0 if not,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) * or -1 if the instruction is one that should not be stepped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) * such as an rfid, or a mtmsrd that would clear MSR_RI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) int emulate_step(struct pt_regs *regs, struct ppc_inst instr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) struct instruction_op op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) int r, err, type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) unsigned long ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) r = analyse_instr(&op, regs, instr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) if (r > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) emulate_update_regs(regs, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) type = GETTYPE(op.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) if (OP_IS_LOAD_STORE(type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) err = emulate_loadstore(regs, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) goto instr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) case CACHEOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) ea = truncate_if_32bit(regs->msr, op.ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) if (!address_ok(regs, ea, 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) switch (op.type & CACHEOP_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) case DCBST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) __cacheop_user_asmx(ea, err, "dcbst");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) case DCBF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) __cacheop_user_asmx(ea, err, "dcbf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) case DCBTST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) if (op.reg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) prefetchw((void *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) case DCBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) if (op.reg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) prefetch((void *) ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) case ICBI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) __cacheop_user_asmx(ea, err, "icbi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) case DCBZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) err = emulate_dcbz(ea, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) regs->dar = ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) goto instr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) case MFMSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) regs->gpr[op.reg] = regs->msr & MSR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) goto instr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) case MTMSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) val = regs->gpr[op.reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) if ((val & MSR_RI) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) /* can't step mtmsr[d] that would clear MSR_RI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) /* here op.val is the mask of bits to change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) regs->msr = (regs->msr & ~op.val) | (val & op.val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) goto instr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) #ifdef CONFIG_PPC64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) case SYSCALL: /* sc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) * N.B. this uses knowledge about how the syscall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) * entry code works. If that is changed, this will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) * need to be changed also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) if (IS_ENABLED(CONFIG_PPC_FAST_ENDIAN_SWITCH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) cpu_has_feature(CPU_FTR_REAL_LE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) regs->gpr[0] == 0x1ebe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) regs->msr ^= MSR_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) goto instr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) regs->gpr[9] = regs->gpr[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) regs->gpr[10] = MSR_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) regs->gpr[11] = regs->nip + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) regs->gpr[12] = regs->msr & MSR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) regs->gpr[13] = (unsigned long) get_paca();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) regs->nip = (unsigned long) &system_call_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) regs->msr = MSR_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) #ifdef CONFIG_PPC_BOOK3S_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) case SYSCALL_VECTORED_0: /* scv 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) regs->gpr[9] = regs->gpr[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) regs->gpr[10] = MSR_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) regs->gpr[11] = regs->nip + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) regs->gpr[12] = regs->msr & MSR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) regs->gpr[13] = (unsigned long) get_paca();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) regs->nip = (unsigned long) &system_call_vectored_emulate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) regs->msr = MSR_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) case RFI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) instr_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) regs->nip = truncate_if_32bit(regs->msr, regs->nip + GETLENGTH(op.type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) NOKPROBE_SYMBOL(emulate_step);