114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* 214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Single-step support. 314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Copyright (C) 2004 Paul Mackerras <paulus@au.ibm.com>, IBM 514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * This program is free software; you can redistribute it and/or 714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * modify it under the terms of the GNU General Public License 814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * as published by the Free Software Foundation; either version 914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * 2 of the License, or (at your option) any later version. 1014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 1114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/kernel.h> 120d69a052d4d7c4085706b9ac0d1bd28ff90c9fcaGui,Jian#include <linux/kprobes.h> 1314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <linux/ptrace.h> 14268bb0ce3e87872cb9290c322b0d35bce230d88fLinus Torvalds#include <linux/prefetch.h> 1514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/sstep.h> 1614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras#include <asm/processor.h> 170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#include <asm/uaccess.h> 180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#include <asm/cputable.h> 1914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 2014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerrasextern char system_call_common[]; 2114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 22c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#ifdef CONFIG_PPC64 2314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* Bits in SRR1 that are copied from MSR */ 24af308377e204e25f1f58627d05fe0f483703b514Stephen Rothwell#define MSR_MASK 0xffffffff87c0ffffUL 25c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#else 26c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#define MSR_MASK 0x87c0ffff 27c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#endif 2814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* Bits in XER */ 300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define XER_SO 0x80000000U 310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define XER_OV 0x40000000U 320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define XER_CA 0x20000000U 330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 34cd64d1697cf079bb8a67766e36e88ced38498933Sean MacLennan#ifdef CONFIG_PPC_FPU 350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Functions in ldstfp.S 370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_lfs(int rn, unsigned long ea); 390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_lfd(int rn, unsigned long ea); 400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_stfs(int rn, unsigned long ea); 410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_stfd(int rn, unsigned long ea); 420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_lvx(int rn, unsigned long ea); 430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_stvx(int rn, unsigned long ea); 440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_lxvd2x(int rn, unsigned long ea); 450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasextern int do_stxvd2x(int rn, unsigned long ea); 46cd64d1697cf079bb8a67766e36e88ced38498933Sean MacLennan#endif 470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* 49b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman * Emulate the truncation of 64 bit values in 32-bit mode. 50b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman */ 51b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellermanstatic unsigned long truncate_if_32bit(unsigned long msr, unsigned long val) 52b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman{ 53b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman#ifdef __powerpc64__ 54b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman if ((msr & MSR_64BIT) == 0) 55b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman val &= 0xffffffffUL; 56b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman#endif 57b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman return val; 58b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman} 59b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman 60b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman/* 6114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras * Determine whether a conditional branch instruction would branch. 6214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 630d69a052d4d7c4085706b9ac0d1bd28ff90c9fcaGui,Jianstatic int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) 6414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 6514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned int bo = (instr >> 21) & 0x1f; 6614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned int bi; 6714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 6814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if ((bo & 4) == 0) { 6914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* decrement counter */ 7014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras --regs->ctr; 7114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (((bo >> 1) & 1) ^ (regs->ctr == 0)) 7214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 7314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 7414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if ((bo & 0x10) == 0) { 7514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras /* check bit from CR */ 7614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras bi = (instr >> 16) & 0x1f; 7714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1)) 7814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 0; 7914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 8014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 1; 8114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 8214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic long __kprobes address_ok(struct pt_regs *regs, unsigned long ea, int nb) 850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!user_mode(regs)) 870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return 1; 880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return __access_ok(ea, nb, USER_DS); 890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Calculate effective address for a D-form instruction 930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic unsigned long __kprobes dform_ea(unsigned int instr, struct pt_regs *regs) 950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int ra; 970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea; 980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ra = (instr >> 16) & 0x1f; 1000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ea = (signed short) instr; /* sign-extend */ 101be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (ra) 1020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ea += regs->gpr[ra]; 103b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman 104b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman return truncate_if_32bit(regs->msr, ea); 1050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 1080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 1090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Calculate effective address for a DS-form instruction 1100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 1110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic unsigned long __kprobes dsform_ea(unsigned int instr, struct pt_regs *regs) 1120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 1130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int ra; 1140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea; 1150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ra = (instr >> 16) & 0x1f; 1170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ea = (signed short) (instr & ~3); /* sign-extend */ 118be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (ra) 1190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ea += regs->gpr[ra]; 120b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman 121b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman return truncate_if_32bit(regs->msr, ea); 1220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif /* __powerpc64 */ 1240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 1260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Calculate effective address for an X-form instruction 1270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 128be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerrasstatic unsigned long __kprobes xform_ea(unsigned int instr, 129be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras struct pt_regs *regs) 1300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 1310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int ra, rb; 1320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea; 1330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ra = (instr >> 16) & 0x1f; 1350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras rb = (instr >> 11) & 0x1f; 1360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ea = regs->gpr[rb]; 137be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (ra) 1380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ea += regs->gpr[ra]; 139b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman 140b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman return truncate_if_32bit(regs->msr, ea); 1410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 1440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Return the largest power of 2, not greater than sizeof(unsigned long), 1450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * such that x is a multiple of it. 1460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 1470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic inline unsigned long max_align(unsigned long x) 1480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 1490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras x |= sizeof(unsigned long); 1500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return x & -x; /* isolates rightmost bit */ 1510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic inline unsigned long byterev_2(unsigned long x) 1550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 1560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return ((x >> 8) & 0xff) | ((x & 0xff) << 8); 1570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic inline unsigned long byterev_4(unsigned long x) 1600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 1610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) | 1620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ((x & 0xff00) << 8) | ((x & 0xff) << 24); 1630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 1660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic inline unsigned long byterev_8(unsigned long x) 1670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 1680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (byterev_4(x) << 32) | byterev_4(x >> 32); 1690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 1710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes read_mem_aligned(unsigned long *dest, unsigned long ea, 1730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int nb) 1740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 1750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err = 0; 1760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long x = 0; 1770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch (nb) { 1790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1: 1800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __get_user(x, (unsigned char __user *) ea); 1810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 1820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 2: 1830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __get_user(x, (unsigned short __user *) ea); 1840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 1850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 4: 1860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __get_user(x, (unsigned int __user *) ea); 1870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 1880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 1890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 8: 1900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __get_user(x, (unsigned long __user *) ea); 1910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 1920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 1930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 1940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!err) 1950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras *dest = x; 1960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 1970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 1980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea, 2000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int nb, struct pt_regs *regs) 2010016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 2020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err; 2030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long x, b, c; 2046506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __LITTLE_ENDIAN__ 2056506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta int len = nb; /* save a copy of the length for byte reversal */ 2066506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 2070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 2080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* unaligned, do this in pieces */ 2090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras x = 0; 2100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras for (; nb > 0; nb -= c) { 2116506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __LITTLE_ENDIAN__ 2126506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta c = 1; 2136506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 2146506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __BIG_ENDIAN__ 2150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras c = max_align(ea); 2166506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 2170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (c > nb) 2180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras c = max_align(nb); 2190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = read_mem_aligned(&b, ea, c); 2200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (err) 2210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 2220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras x = (x << (8 * c)) + b; 2230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ea += c; 2240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 2256506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __LITTLE_ENDIAN__ 2266506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta switch (len) { 2276506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta case 2: 2286506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta *dest = byterev_2(x); 2296506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta break; 2306506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta case 4: 2316506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta *dest = byterev_4(x); 2326506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta break; 2336506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __powerpc64__ 2346506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta case 8: 2356506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta *dest = byterev_8(x); 2366506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta break; 2376506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 2386506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta } 2396506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 2406506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __BIG_ENDIAN__ 2410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras *dest = x; 2426506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 2430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return 0; 2440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 2450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 2460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 2470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Read memory at address ea for nb bytes, return 0 for success 2480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * or -EFAULT if an error occurred. 2490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 2500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes read_mem(unsigned long *dest, unsigned long ea, int nb, 2510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras struct pt_regs *regs) 2520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 2530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea, nb)) 2540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 2550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((ea & (nb - 1)) == 0) 2560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return read_mem_aligned(dest, ea, nb); 2570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return read_mem_unaligned(dest, ea, nb, regs); 2580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 2590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 2600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes write_mem_aligned(unsigned long val, unsigned long ea, 2610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int nb) 2620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 2630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err = 0; 2640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 2650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch (nb) { 2660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1: 2670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __put_user(val, (unsigned char __user *) ea); 2680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 2690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 2: 2700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __put_user(val, (unsigned short __user *) ea); 2710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 2720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 4: 2730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __put_user(val, (unsigned int __user *) ea); 2740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 2750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 2760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 8: 2770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = __put_user(val, (unsigned long __user *) ea); 2780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 2790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 2800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 2810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 2820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 2830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 2840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea, 2850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int nb, struct pt_regs *regs) 2860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 2870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err; 2880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long c; 2890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 2906506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __LITTLE_ENDIAN__ 2916506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta switch (nb) { 2926506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta case 2: 2936506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta val = byterev_2(val); 2946506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta break; 2956506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta case 4: 2966506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta val = byterev_4(val); 2976506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta break; 2986506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __powerpc64__ 2996506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta case 8: 3006506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta val = byterev_8(val); 3016506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta break; 3026506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 3036506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta } 3046506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 3050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* unaligned or little-endian, do this in pieces */ 3060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras for (; nb > 0; nb -= c) { 3076506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __LITTLE_ENDIAN__ 3086506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta c = 1; 3096506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 3106506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#ifdef __BIG_ENDIAN__ 3110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras c = max_align(ea); 3126506b4718bb59c5d4e59235b81b5e13ea5d3c49aTom Musta#endif 3130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (c > nb) 3140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras c = max_align(nb); 3150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = write_mem_aligned(val >> (nb - c) * 8, ea, c); 3160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (err) 3170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 31817e8de7e1878bbd45f3e268932e997496ddbbfe7Tom Musta ea += c; 3190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 3200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return 0; 3210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 3220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 3230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 3240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Write memory at address ea for nb bytes, return 0 for success 3250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * or -EFAULT if an error occurred. 3260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 3270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes write_mem(unsigned long val, unsigned long ea, int nb, 3280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras struct pt_regs *regs) 3290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 3300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea, nb)) 3310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 3320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((ea & (nb - 1)) == 0) 3330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return write_mem_aligned(val, ea, nb); 3340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return write_mem_unaligned(val, ea, nb, regs); 3350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 3360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 337cd64d1697cf079bb8a67766e36e88ced38498933Sean MacLennan#ifdef CONFIG_PPC_FPU 33814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras/* 3390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Check the address and alignment, and call func to do the actual 3400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * load or store. 3410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 3420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long), 3430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea, int nb, 3440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras struct pt_regs *regs) 3450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 3460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err; 347dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta union { 348dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta double dbl; 349dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned long ul[2]; 350dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta struct { 351dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#ifdef __BIG_ENDIAN__ 352dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned _pad_; 353dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned word; 354dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#endif 355dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#ifdef __LITTLE_ENDIAN__ 356dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned word; 357dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned _pad_; 358dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#endif 359dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta } single; 360dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta } data; 3610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ptr; 3620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 3630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea, nb)) 3640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 3650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((ea & 3) == 0) 3660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (*func)(rn, ea); 367dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta ptr = (unsigned long) &data.ul; 3680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (sizeof(unsigned long) == 8 || nb == 4) { 369dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta err = read_mem_unaligned(&data.ul[0], ea, nb, regs); 370dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta if (nb == 4) 371dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta ptr = (unsigned long)&(data.single.word); 3720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } else { 3730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* reading a double on 32-bit */ 374dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta err = read_mem_unaligned(&data.ul[0], ea, 4, regs); 3750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!err) 376dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta err = read_mem_unaligned(&data.ul[1], ea + 4, 4, regs); 3770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 3780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (err) 3790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 3800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (*func)(rn, ptr); 3810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 3820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 3830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long), 3840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea, int nb, 3850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras struct pt_regs *regs) 3860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 3870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err; 388dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta union { 389dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta double dbl; 390dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned long ul[2]; 391dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta struct { 392dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#ifdef __BIG_ENDIAN__ 393dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned _pad_; 394dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned word; 395dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#endif 396dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#ifdef __LITTLE_ENDIAN__ 397dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned word; 398dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta unsigned _pad_; 399dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta#endif 400dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta } single; 401dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta } data; 4020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ptr; 4030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea, nb)) 4050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 4060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((ea & 3) == 0) 4070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (*func)(rn, ea); 408dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta ptr = (unsigned long) &data.ul[0]; 4090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (sizeof(unsigned long) == 8 || nb == 4) { 410dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta if (nb == 4) 411dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta ptr = (unsigned long)&(data.single.word); 4120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = (*func)(rn, ptr); 4130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (err) 4140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 415dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta err = write_mem_unaligned(data.ul[0], ea, nb, regs); 4160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } else { 4170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* writing a double on 32-bit */ 4180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = (*func)(rn, ptr); 4190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (err) 4200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 421dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta err = write_mem_unaligned(data.ul[0], ea, 4, regs); 4220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!err) 423dbc2fbd7c29a78724e761711d516930246c0e1c2Tom Musta err = write_mem_unaligned(data.ul[1], ea + 4, 4, regs); 4240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 4250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 4260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 427cd64d1697cf079bb8a67766e36e88ced38498933Sean MacLennan#endif 4280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef CONFIG_ALTIVEC 4300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* For Altivec/VMX, no need to worry about alignment */ 4310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes do_vec_load(int rn, int (*func)(int, unsigned long), 4320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea, struct pt_regs *regs) 4330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 4340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea & ~0xfUL, 16)) 4350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 4360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (*func)(rn, ea); 4370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 4380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes do_vec_store(int rn, int (*func)(int, unsigned long), 4400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea, struct pt_regs *regs) 4410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 4420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea & ~0xfUL, 16)) 4430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 4440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (*func)(rn, ea); 4450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 4460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif /* CONFIG_ALTIVEC */ 4470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef CONFIG_VSX 4490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes do_vsx_load(int rn, int (*func)(int, unsigned long), 4500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea, struct pt_regs *regs) 4510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 4520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err; 4530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long val[2]; 4540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea, 16)) 4560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 4570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((ea & 3) == 0) 4580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (*func)(rn, ea); 4590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = read_mem_unaligned(&val[0], ea, 8, regs); 4600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!err) 4610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = read_mem_unaligned(&val[1], ea + 8, 8, regs); 4620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!err) 4630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = (*func)(rn, (unsigned long) &val[0]); 4640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 4650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 4660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic int __kprobes do_vsx_store(int rn, int (*func)(int, unsigned long), 4680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long ea, struct pt_regs *regs) 4690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 4700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int err; 4710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long val[2]; 4720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!address_ok(regs, ea, 16)) 4740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return -EFAULT; 4750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((ea & 3) == 0) 4760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return (*func)(rn, ea); 4770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = (*func)(rn, (unsigned long) &val[0]); 4780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (err) 4790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 4800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = write_mem_unaligned(val[0], ea, 8, regs); 4810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!err) 4820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras err = write_mem_unaligned(val[1], ea + 8, 8, regs); 4830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return err; 4840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 4850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif /* CONFIG_VSX */ 4860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 4870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define __put_user_asmx(x, addr, err, op, cr) \ 4880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras __asm__ __volatile__( \ 4890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "1: " op " %2,0,%3\n" \ 4900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras " mfcr %1\n" \ 4910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "2:\n" \ 4920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".section .fixup,\"ax\"\n" \ 4930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "3: li %0,%4\n" \ 4940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras " b 2b\n" \ 4950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".previous\n" \ 4960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".section __ex_table,\"a\"\n" \ 4970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras PPC_LONG_ALIGN "\n" \ 4980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras PPC_LONG "1b,3b\n" \ 4990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".previous" \ 5000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras : "=r" (err), "=r" (cr) \ 5010016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)) 5020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define __get_user_asmx(x, addr, err, op) \ 5040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras __asm__ __volatile__( \ 5050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "1: "op" %1,0,%2\n" \ 5060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "2:\n" \ 5070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".section .fixup,\"ax\"\n" \ 5080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "3: li %0,%3\n" \ 5090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras " b 2b\n" \ 5100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".previous\n" \ 5110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".section __ex_table,\"a\"\n" \ 5120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras PPC_LONG_ALIGN "\n" \ 5130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras PPC_LONG "1b,3b\n" \ 5140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".previous" \ 5150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras : "=r" (err), "=r" (x) \ 5160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras : "r" (addr), "i" (-EFAULT), "0" (err)) 5170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define __cacheop_user_asmx(addr, err, op) \ 5190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras __asm__ __volatile__( \ 5200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "1: "op" 0,%1\n" \ 5210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "2:\n" \ 5220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".section .fixup,\"ax\"\n" \ 5230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "3: li %0,%3\n" \ 5240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras " b 2b\n" \ 5250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".previous\n" \ 5260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".section __ex_table,\"a\"\n" \ 5270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras PPC_LONG_ALIGN "\n" \ 5280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras PPC_LONG "1b,3b\n" \ 5290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ".previous" \ 5300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras : "=r" (err) \ 5310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras : "r" (addr), "i" (-EFAULT), "0" (err)) 5320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic void __kprobes set_cr0(struct pt_regs *regs, int rd) 5340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 5350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras long val = regs->gpr[rd]; 5360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); 5380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 539b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman if (!(regs->msr & MSR_64BIT)) 5400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = (int) val; 5410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 5420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (val < 0) 5430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr |= 0x80000000; 5440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else if (val > 0) 5450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr |= 0x40000000; 5460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 5470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr |= 0x20000000; 5480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 5490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic void __kprobes add_with_carry(struct pt_regs *regs, int rd, 5510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long val1, unsigned long val2, 5520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long carry_in) 5530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 5540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long val = val1 + val2; 5550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (carry_in) 5570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ++val; 5580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = val; 5590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 560b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman if (!(regs->msr & MSR_64BIT)) { 5610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = (unsigned int) val; 5620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val1 = (unsigned int) val1; 5630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 5640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 5650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (val < val1 || (carry_in && val == val1)) 5660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer |= XER_CA; 5670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 5680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer &= ~XER_CA; 5690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 5700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic void __kprobes do_cmp_signed(struct pt_regs *regs, long v1, long v2, 5720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras int crfld) 5730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 5740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned int crval, shift; 5750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval = (regs->xer >> 31) & 1; /* get SO bit */ 5770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (v1 < v2) 5780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval |= 8; 5790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else if (v1 > v2) 5800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval |= 4; 5810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 5820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval |= 2; 5830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras shift = (7 - crfld) * 4; 5840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); 5850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 5860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerrasstatic void __kprobes do_cmp_unsigned(struct pt_regs *regs, unsigned long v1, 5880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long v2, int crfld) 5890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras{ 5900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned int crval, shift; 5910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 5920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval = (regs->xer >> 31) & 1; /* get SO bit */ 5930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (v1 < v2) 5940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval |= 8; 5950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else if (v1 > v2) 5960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval |= 4; 5970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 5980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras crval |= 2; 5990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras shift = (7 - crfld) * 4; 6000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); 6010016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras} 6020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 603cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerrasstatic int __kprobes trap_compare(long v1, long v2) 604cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras{ 605cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras int ret = 0; 606cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras 607cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras if (v1 < v2) 608cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras ret |= 0x10; 609cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras else if (v1 > v2) 610cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras ret |= 0x08; 611cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras else 612cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras ret |= 0x04; 613cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras if ((unsigned long)v1 < (unsigned long)v2) 614cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras ret |= 0x02; 615cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras else if ((unsigned long)v1 > (unsigned long)v2) 616cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras ret |= 0x01; 617cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras return ret; 618cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras} 619cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras 6200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 6210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Elements of 32-bit rotate and mask instructions. 6220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 6230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define MASK32(mb, me) ((0xffffffffUL >> (mb)) + \ 6240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ((signed long)-0x80000000L >> (me)) + ((me) >= (mb))) 6250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 6260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define MASK64_L(mb) (~0UL >> (mb)) 6270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define MASK64_R(me) ((signed long)-0x8000000000000000L >> (me)) 6280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define MASK64(mb, me) (MASK64_L(mb) + MASK64_R(me) + ((me) >= (mb))) 6290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define DATA32(x) (((x) & 0xffffffffUL) | (((x) & 0xffffffffUL) << 32)) 6300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#else 6310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define DATA32(x) (x) 6320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 6330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long) - (n)))) : (x)) 6340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 6350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 636be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Decode an instruction, and execute it if that can be done just by 637be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * modifying *regs (i.e. integer arithmetic and logical instructions, 638be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * branches, and barrier instructions). 639be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Returns 1 if the instruction has been executed, or 0 if not. 640be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Sets *op to indicate what the instruction does. 64114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras */ 642be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerrasint __kprobes analyse_instr(struct instruction_op *op, struct pt_regs *regs, 643be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras unsigned int instr) 64414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras{ 6450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned int opcode, ra, rb, rd, spr, u; 64614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras unsigned long int imm; 6470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras unsigned long int val, val2; 648be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras unsigned int mb, me, sh; 6490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras long ival; 65014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras 651be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = COMPUTE; 652be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 65314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras opcode = instr >> 26; 65414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras switch (opcode) { 65514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras case 16: /* bc */ 656be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = BRANCH; 65714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras imm = (signed short)(instr & 0xfffc); 65814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if ((instr & 2) == 0) 65914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras imm += regs->nip; 66014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras regs->nip += 4; 661b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman regs->nip = truncate_if_32bit(regs->msr, regs->nip); 66214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (instr & 1) 66314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras regs->link = regs->nip; 66414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (branch_taken(instr, regs)) 66570a54a4faec72ee9d12b9c4dfa27bc241deb79a6Michael Neuling regs->nip = truncate_if_32bit(regs->msr, imm); 66614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 1; 667c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#ifdef CONFIG_PPC64 66814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras case 17: /* sc */ 669be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if ((instr & 0xfe2) == 2) 670be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = SYSCALL; 671be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras else 672be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = UNKNOWN; 673be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 674c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#endif 67514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras case 18: /* b */ 676be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = BRANCH; 67714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras imm = instr & 0x03fffffc; 67814cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (imm & 0x02000000) 67914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras imm -= 0x04000000; 68014cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if ((instr & 2) == 0) 68114cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras imm += regs->nip; 682b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman if (instr & 1) 683b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman regs->link = truncate_if_32bit(regs->msr, regs->nip + 4); 684b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman imm = truncate_if_32bit(regs->msr, imm); 68514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras regs->nip = imm; 68614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 1; 68714cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras case 19: 6880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch ((instr >> 1) & 0x3ff) { 689cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras case 0: /* mcrf */ 690cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras rd = (instr >> 21) & 0x1c; 691cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras ra = (instr >> 16) & 0x1c; 692cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras val = (regs->ccr >> ra) & 0xf; 693cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd); 694cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto instr_done; 695cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras 6960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 16: /* bclr */ 6970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 528: /* bcctr */ 698be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = BRANCH; 69914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras imm = (instr & 0x400)? regs->ctr: regs->link; 700b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); 701b91e136cdf88e19e998dbf4631ead266de4b80b5Michael Ellerman imm = truncate_if_32bit(regs->msr, imm); 70214cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (instr & 1) 70314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras regs->link = regs->nip; 70414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras if (branch_taken(instr, regs)) 70514cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras regs->nip = imm; 70614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras return 1; 7070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 18: /* rfid, scary */ 709be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_PR) 710be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto priv; 711be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = RFI; 712be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 7130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 150: /* isync */ 715be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = BARRIER; 7160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras isync(); 7170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 33: /* crnor */ 7200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 129: /* crandc */ 7210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 193: /* crxor */ 7220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 225: /* crnand */ 7230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 257: /* crand */ 7240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 289: /* creqv */ 7250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 417: /* crorc */ 7260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 449: /* cror */ 7270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ra = (instr >> 16) & 0x1f; 7280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras rb = (instr >> 11) & 0x1f; 7290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras rd = (instr >> 21) & 0x1f; 7300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ra = (regs->ccr >> (31 - ra)) & 1; 7310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras rb = (regs->ccr >> (31 - rb)) & 1; 7320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = (instr >> (6 + ra * 2 + rb)) & 1; 7330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr = (regs->ccr & ~(1UL << (31 - rd))) | 7340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras (val << (31 - rd)); 7350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 7370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 7380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 31: 7390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch ((instr >> 1) & 0x3ff) { 7400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 598: /* sync */ 741be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = BARRIER; 7420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 7430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch ((instr >> 21) & 3) { 7440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1: /* lwsync */ 7450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm volatile("lwsync" : : : "memory"); 7460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 2: /* ptesync */ 7480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm volatile("ptesync" : : : "memory"); 7490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 7510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 7520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras mb(); 7530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 854: /* eieio */ 756be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = BARRIER; 7570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras eieio(); 7580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 7600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 7610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 7620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* Following cases refer to regs->gpr[], so we need all regs */ 7640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!FULL_REGS(regs)) 7650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras return 0; 7660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras rd = (instr >> 21) & 0x1f; 7680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ra = (instr >> 16) & 0x1f; 7690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras rb = (instr >> 11) & 0x1f; 7700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch (opcode) { 772cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras#ifdef __powerpc64__ 773cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras case 2: /* tdi */ 774cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras if (rd & trap_compare(regs->gpr[ra], (short) instr)) 775cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto trap; 776cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto instr_done; 777cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras#endif 778cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras case 3: /* twi */ 779cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras if (rd & trap_compare((int)regs->gpr[ra], (short) instr)) 780cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto trap; 781cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto instr_done; 782cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras 7830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 7: /* mulli */ 7840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = regs->gpr[ra] * (short) instr; 7850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 8: /* subfic */ 7880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (short) instr; 7890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, ~regs->gpr[ra], imm, 1); 7900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 7910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 7920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 10: /* cmpli */ 7930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (unsigned short) instr; 7940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = regs->gpr[ra]; 7950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 7960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((rd & 1) == 0) 7970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = (unsigned int) val; 7980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 7990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras do_cmp_unsigned(regs, val, imm, rd >> 2); 8000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8010016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 11: /* cmpi */ 8030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (short) instr; 8040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = regs->gpr[ra]; 8050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 8060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((rd & 1) == 0) 8070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = (int) val; 8080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 8090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras do_cmp_signed(regs, val, imm, rd >> 2); 8100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 12: /* addic */ 8130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (short) instr; 8140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, regs->gpr[ra], imm, 0); 8150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 13: /* addic. */ 8180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (short) instr; 8190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, regs->gpr[ra], imm, 0); 8200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras set_cr0(regs, rd); 8210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 14: /* addi */ 8240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (short) instr; 8250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (ra) 8260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm += regs->gpr[ra]; 8270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = imm; 8280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 15: /* addis */ 8310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = ((short) instr) << 16; 8320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (ra) 8330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm += regs->gpr[ra]; 8340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = imm; 8350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 20: /* rlwimi */ 8380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras mb = (instr >> 6) & 0x1f; 8390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras me = (instr >> 1) & 0x1f; 8400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = DATA32(regs->gpr[rd]); 8410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = MASK32(mb, me); 8420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); 8430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 8440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 21: /* rlwinm */ 8460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras mb = (instr >> 6) & 0x1f; 8470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras me = (instr >> 1) & 0x1f; 8480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = DATA32(regs->gpr[rd]); 8490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); 8500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 8510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 23: /* rlwnm */ 8530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras mb = (instr >> 6) & 0x1f; 8540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras me = (instr >> 1) & 0x1f; 8550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras rb = regs->gpr[rb] & 0x1f; 8560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = DATA32(regs->gpr[rd]); 8570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); 8580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 8590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 24: /* ori */ 8610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (unsigned short) instr; 8620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] | imm; 8630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 25: /* oris */ 8660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (unsigned short) instr; 8670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] | (imm << 16); 8680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 26: /* xori */ 8710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (unsigned short) instr; 8720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] ^ imm; 8730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 27: /* xoris */ 8760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (unsigned short) instr; 8770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] ^ (imm << 16); 8780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 28: /* andi. */ 8810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (unsigned short) instr; 8820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] & imm; 8830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras set_cr0(regs, ra); 8840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 29: /* andis. */ 8870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = (unsigned short) instr; 8880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] & (imm << 16); 8890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras set_cr0(regs, ra); 8900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 8910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 8920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 8930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 30: /* rld* */ 8940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras mb = ((instr >> 6) & 0x1f) | (instr & 0x20); 8950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = regs->gpr[rd]; 8960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((instr & 0x10) == 0) { 8970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = rb | ((instr & 2) << 4); 8980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = ROTATE(val, sh); 8990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch ((instr >> 2) & 3) { 9000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 0: /* rldicl */ 9010016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = val & MASK64_L(mb); 9020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 9030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1: /* rldicr */ 9040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = val & MASK64_R(mb); 9050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 9060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 2: /* rldic */ 9070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = val & MASK64(mb, 63 - sh); 9080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 9090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 3: /* rldimi */ 9100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = MASK64(mb, 63 - sh); 9110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = (regs->gpr[ra] & ~imm) | 9120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras (val & imm); 9130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 9140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 9150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } else { 9160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = regs->gpr[rb] & 0x3f; 9170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = ROTATE(val, sh); 9180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch ((instr >> 1) & 7) { 9190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 0: /* rldcl */ 9200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = val & MASK64_L(mb); 9210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 9220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1: /* rldcr */ 9230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = val & MASK64_R(mb); 9240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 9250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 92614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 9270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 9280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 92914cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras case 31: 9300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch ((instr >> 1) & 0x3ff) { 931cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras case 4: /* tw */ 932cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras if (rd == 0x1f || 933cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras (rd & trap_compare((int)regs->gpr[ra], 934cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras (int)regs->gpr[rb]))) 935cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto trap; 936cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto instr_done; 937cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras#ifdef __powerpc64__ 938cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras case 68: /* td */ 939cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras if (rd & trap_compare(regs->gpr[ra], regs->gpr[rb])) 940cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto trap; 941cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras goto instr_done; 942cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras#endif 9430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 83: /* mfmsr */ 9440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (regs->msr & MSR_PR) 945be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto priv; 946be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MFMSR; 947be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd; 948be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 9490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 146: /* mtmsr */ 9500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (regs->msr & MSR_PR) 951be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto priv; 952be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MTMSR; 953be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd; 954be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = 0xffffffff & ~(MSR_ME | MSR_LE); 955be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 956c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#ifdef CONFIG_PPC64 9570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 178: /* mtmsrd */ 9580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (regs->msr & MSR_PR) 959be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto priv; 960be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MTMSR; 961be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd; 962be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras /* only MSR_EE and MSR_RI get changed if bit 15 set */ 963be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras /* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */ 964be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras imm = (instr & 0x10000)? 0x8002: 0xefffffffffffeffeUL; 965be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = imm; 966be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 967c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cdPaul Mackerras#endif 968be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 9690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 19: /* mfcr */ 9706888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->gpr[rd] = regs->ccr; 9716888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->gpr[rd] &= 0xffffffffUL; 9720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 9730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 9740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 144: /* mtcrf */ 9750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm = 0xf0000000UL; 9760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = regs->gpr[rd]; 9770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras for (sh = 0; sh < 8; ++sh) { 9780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (instr & (0x80000 >> sh)) 9790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->ccr = (regs->ccr & ~imm) | 9800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras (val & imm); 9810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras imm >>= 4; 9820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 9830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 9840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 9850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 339: /* mfspr */ 986be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); 9876888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli switch (spr) { 988be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case SPRN_XER: /* mfxer */ 9896888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->gpr[rd] = regs->xer; 9906888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->gpr[rd] &= 0xffffffffUL; 9910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 992be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case SPRN_LR: /* mflr */ 9936888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->gpr[rd] = regs->link; 9940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 995be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case SPRN_CTR: /* mfctr */ 9966888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->gpr[rd] = regs->ctr; 9970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 998be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras default: 999be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MFSPR; 1000be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd; 1001be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->spr = spr; 1002be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 10036888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli } 10046888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli break; 10050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 467: /* mtspr */ 1007be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); 10086888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli switch (spr) { 1009be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case SPRN_XER: /* mtxer */ 10106888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->xer = (regs->gpr[rd] & 0xffffffffUL); 10110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 1012be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case SPRN_LR: /* mtlr */ 10136888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->link = regs->gpr[rd]; 10140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 1015be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case SPRN_CTR: /* mtctr */ 10166888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli regs->ctr = regs->gpr[rd]; 10170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 1018be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras default: 1019be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MTSPR; 1020be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = regs->gpr[rd]; 1021be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->spr = spr; 1022be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 10236888199f7fe5ea496f48bb6de67b9b7f05b8071bAnanth N Mavinakayanahalli } 10240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 10250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 10270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Compare instructions 10280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 10290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 0: /* cmp */ 10300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = regs->gpr[ra]; 10310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val2 = regs->gpr[rb]; 10320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 10330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((rd & 1) == 0) { 10340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* word (32-bit) compare */ 10350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = (int) val; 10360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val2 = (int) val2; 10370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 10380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 10390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras do_cmp_signed(regs, val, val2, rd >> 2); 10400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 10410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 32: /* cmpl */ 10430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = regs->gpr[ra]; 10440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val2 = regs->gpr[rb]; 10450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 10460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if ((rd & 1) == 0) { 10470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* word (32-bit) compare */ 10480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val = (unsigned int) val; 10490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras val2 = (unsigned int) val2; 10500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 10510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 10520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras do_cmp_unsigned(regs, val, val2, rd >> 2); 10530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 10540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 10560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Arithmetic instructions 10570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 10580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 8: /* subfc */ 10590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, ~regs->gpr[ra], 10600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rb], 1); 10610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 10630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 9: /* mulhdu */ 10640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm("mulhdu %0,%1,%2" : "=r" (regs->gpr[rd]) : 10650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); 10660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 10680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 10: /* addc */ 10690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, regs->gpr[ra], 10700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rb], 0); 10710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 11: /* mulhwu */ 10740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm("mulhwu %0,%1,%2" : "=r" (regs->gpr[rd]) : 10750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); 10760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 40: /* subf */ 10790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = regs->gpr[rb] - regs->gpr[ra]; 10800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 10820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 73: /* mulhd */ 10830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm("mulhd %0,%1,%2" : "=r" (regs->gpr[rd]) : 10840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); 10850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 10870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 75: /* mulhw */ 10880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm("mulhw %0,%1,%2" : "=r" (regs->gpr[rd]) : 10890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); 10900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 104: /* neg */ 10930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = -regs->gpr[ra]; 10940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 10950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 10960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 136: /* subfe */ 10970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, ~regs->gpr[ra], regs->gpr[rb], 10980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer & XER_CA); 10990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11010016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 138: /* adde */ 11020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, regs->gpr[ra], regs->gpr[rb], 11030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer & XER_CA); 11040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 200: /* subfze */ 11070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, ~regs->gpr[ra], 0L, 11080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer & XER_CA); 11090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 202: /* addze */ 11120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, regs->gpr[ra], 0L, 11130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer & XER_CA); 11140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 232: /* subfme */ 11170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, ~regs->gpr[ra], -1L, 11180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer & XER_CA); 11190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 11210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 233: /* mulld */ 11220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = regs->gpr[ra] * regs->gpr[rb]; 11230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 11250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 234: /* addme */ 11260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras add_with_carry(regs, rd, regs->gpr[ra], -1L, 11270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer & XER_CA); 11280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 235: /* mullw */ 11310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = (unsigned int) regs->gpr[ra] * 11320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras (unsigned int) regs->gpr[rb]; 11330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 266: /* add */ 11360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = regs->gpr[ra] + regs->gpr[rb]; 11370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 11390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 457: /* divdu */ 11400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = regs->gpr[ra] / regs->gpr[rb]; 11410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 11430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 459: /* divwu */ 11440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = (unsigned int) regs->gpr[ra] / 11450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras (unsigned int) regs->gpr[rb]; 11460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 11480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 489: /* divd */ 11490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = (long int) regs->gpr[ra] / 11500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras (long int) regs->gpr[rb]; 11510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 11530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 491: /* divw */ 11540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[rd] = (int) regs->gpr[ra] / 11550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras (int) regs->gpr[rb]; 11560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto arith_done; 11570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 11600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Logical instructions 11610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 11620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 26: /* cntlzw */ 11630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm("cntlzw %0,%1" : "=r" (regs->gpr[ra]) : 11640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "r" (regs->gpr[rd])); 11650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 11670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 58: /* cntlzd */ 11680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras asm("cntlzd %0,%1" : "=r" (regs->gpr[ra]) : 11690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras "r" (regs->gpr[rd])); 11700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 11720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 28: /* and */ 11730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] & regs->gpr[rb]; 11740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 60: /* andc */ 11770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] & ~regs->gpr[rb]; 11780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 124: /* nor */ 11810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]); 11820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 284: /* xor */ 11850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ~(regs->gpr[rd] ^ regs->gpr[rb]); 11860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 316: /* xor */ 11890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] ^ regs->gpr[rb]; 11900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 412: /* orc */ 11930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] | ~regs->gpr[rb]; 11940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 11960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 444: /* or */ 11970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] | regs->gpr[rb]; 11980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 11990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12000016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 476: /* nand */ 12010016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ~(regs->gpr[rd] & regs->gpr[rb]); 12020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 922: /* extsh */ 12050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = (signed short) regs->gpr[rd]; 12060016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 954: /* extsb */ 12090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = (signed char) regs->gpr[rd]; 12100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 12120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 986: /* extsw */ 12130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = (signed int) regs->gpr[rd]; 12140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 12160016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12170016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 12180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Shift instructions 12190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 12200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 24: /* slw */ 12210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = regs->gpr[rb] & 0x3f; 12220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (sh < 32) 12230016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = (regs->gpr[rd] << sh) & 0xffffffffUL; 12240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = 0; 12260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 536: /* srw */ 12290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = regs->gpr[rb] & 0x3f; 12300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (sh < 32) 12310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = (regs->gpr[rd] & 0xffffffffUL) >> sh; 12320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12330016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = 0; 12340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 792: /* sraw */ 12370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = regs->gpr[rb] & 0x3f; 12380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ival = (signed int) regs->gpr[rd]; 12390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ival >> (sh < 32 ? sh : 31); 1240e698b9667879b79e479cc985f9d74ecf126e343ePaul Mackerras if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0)) 12410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer |= XER_CA; 12420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer &= ~XER_CA; 12440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 824: /* srawi */ 12470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = rb; 12480016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ival = (signed int) regs->gpr[rd]; 12490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ival >> sh; 1250e698b9667879b79e479cc985f9d74ecf126e343ePaul Mackerras if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) 12510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer |= XER_CA; 12520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer &= ~XER_CA; 12540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 12570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 27: /* sld */ 1258e698b9667879b79e479cc985f9d74ecf126e343ePaul Mackerras sh = regs->gpr[rb] & 0x7f; 12590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (sh < 64) 12600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] << sh; 12610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = 0; 12630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 539: /* srd */ 12660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = regs->gpr[rb] & 0x7f; 12670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (sh < 64) 12680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = regs->gpr[rd] >> sh; 12690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = 0; 12710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12720016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12730016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 794: /* srad */ 12740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = regs->gpr[rb] & 0x7f; 12750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ival = (signed long int) regs->gpr[rd]; 12760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ival >> (sh < 64 ? sh : 63); 1277e698b9667879b79e479cc985f9d74ecf126e343ePaul Mackerras if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0)) 12780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer |= XER_CA; 12790016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12800016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer &= ~XER_CA; 12810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 826: /* sradi with sh_5 = 0 */ 12840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 827: /* sradi with sh_5 = 1 */ 12850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras sh = rb | ((instr & 2) << 4); 12860016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras ival = (signed long int) regs->gpr[rd]; 12870016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->gpr[ra] = ival >> sh; 1288e698b9667879b79e479cc985f9d74ecf126e343ePaul Mackerras if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) 12890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer |= XER_CA; 12900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras else 12910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras regs->xer &= ~XER_CA; 12920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto logical_done; 12930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif /* __powerpc64__ */ 12940016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 12950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras/* 12960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras * Cache instructions 12970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 12980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 54: /* dcbst */ 1299be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(CACHEOP, DCBST, 0); 1300be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = xform_ea(instr, regs); 1301be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 13020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 86: /* dcbf */ 1304be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(CACHEOP, DCBF, 0); 1305be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = xform_ea(instr, regs); 1306be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 13070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 246: /* dcbtst */ 1309be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(CACHEOP, DCBTST, 0); 1310be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = xform_ea(instr, regs); 1311be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd; 1312be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 13130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 278: /* dcbt */ 1315be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(CACHEOP, DCBTST, 0); 1316be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = xform_ea(instr, regs); 1317be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd; 1318be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1319cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras 1320cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras case 982: /* icbi */ 1321cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras op->type = MKOP(CACHEOP, ICBI, 0); 1322cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras op->ea = xform_ea(instr, regs); 1323cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras return 0; 132414cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 13250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 132614cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras } 13270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras /* 1329be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Loads and stores. 13300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras */ 1331be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = UNKNOWN; 1332be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->update_reg = ra; 1333be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd; 1334be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = regs->gpr[rd]; 1335be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras u = (instr >> 20) & UPDATE; 13360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch (opcode) { 13380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 31: 1339be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras u = instr & UPDATE; 1340be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = xform_ea(instr, regs); 13410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch ((instr >> 1) & 0x3ff) { 13420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 20: /* lwarx */ 1343be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LARX, 0, 4); 1344be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 150: /* stwcx. */ 1347be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STCX, 0, 4); 1348be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13490016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 13510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 84: /* ldarx */ 1352be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LARX, 0, 8); 1353be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 214: /* stdcx. */ 1356be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STCX, 0, 8); 1357be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 21: /* ldx */ 13600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 53: /* ldux */ 1361be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, u, 8); 1362be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 13640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 23: /* lwzx */ 13660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 55: /* lwzux */ 1367be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, u, 4); 1368be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 87: /* lbzx */ 13710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 119: /* lbzux */ 1372be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, u, 1); 1373be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13740016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef CONFIG_ALTIVEC 13760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 103: /* lvx */ 13770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 359: /* lvxl */ 13780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_VEC)) 1379be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto vecunavail; 1380be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD_VMX, 0, 16); 1381be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 231: /* stvx */ 13840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 487: /* stvxl */ 13850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_VEC)) 1386be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto vecunavail; 1387be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE_VMX, 0, 16); 1388be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif /* CONFIG_ALTIVEC */ 13900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13910016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 13920016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 149: /* stdx */ 13930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 181: /* stdux */ 1394be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, u, 8); 1395be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 13960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 13970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 13980016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 151: /* stwx */ 13990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 183: /* stwux */ 1400be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, u, 4); 1401be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 215: /* stbx */ 14040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 247: /* stbux */ 1405be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, u, 1); 1406be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14070016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14080016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 279: /* lhzx */ 14090016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 311: /* lhzux */ 1410be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, u, 2); 1411be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 14140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 341: /* lwax */ 14150016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 373: /* lwaux */ 1416be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, SIGNEXT | u, 4); 1417be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 14190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 343: /* lhax */ 14210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 375: /* lhaux */ 1422be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, SIGNEXT | u, 2); 1423be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14240016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14250016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 407: /* sthx */ 14260016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 439: /* sthux */ 1427be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, u, 2); 1428be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 14310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 532: /* ldbrx */ 1432be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, BYTEREV, 8); 1433be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14340016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 1436c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras case 533: /* lswx */ 1437c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->type = MKOP(LOAD_MULTI, 0, regs->xer & 0x7f); 1438c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras break; 14390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 534: /* lwbrx */ 1441be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, BYTEREV, 4); 1442be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1444c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras case 597: /* lswi */ 1445c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras if (rb == 0) 1446c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras rb = 32; /* # bytes to load */ 1447c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->type = MKOP(LOAD_MULTI, 0, rb); 1448c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->ea = 0; 1449c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras if (ra) 1450c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->ea = truncate_if_32bit(regs->msr, 1451c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras regs->gpr[ra]); 1452c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras break; 1453c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras 1454b69a1da94f3d1589d1942b5d1b384d8cfaac4500Paul Bolle#ifdef CONFIG_PPC_FPU 14550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 535: /* lfsx */ 14560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 567: /* lfsux */ 14570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1458be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1459be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD_FP, u, 4); 1460be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 599: /* lfdx */ 14630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 631: /* lfdux */ 14640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1465be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1466be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD_FP, u, 8); 1467be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14680016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 663: /* stfsx */ 14700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 695: /* stfsux */ 14710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1472be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1473be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE_FP, u, 4); 1474be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 727: /* stfdx */ 14770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 759: /* stfdux */ 14780016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1479be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1480be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE_FP, u, 8); 1481be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1482cd64d1697cf079bb8a67766e36e88ced38498933Sean MacLennan#endif 14830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 14850016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 660: /* stdbrx */ 1486be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, BYTEREV, 8); 1487be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = byterev_8(regs->gpr[rd]); 1488be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 14900016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif 1491c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras case 661: /* stswx */ 1492c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->type = MKOP(STORE_MULTI, 0, regs->xer & 0x7f); 1493c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras break; 1494c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras 14950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 662: /* stwbrx */ 1496be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, BYTEREV, 4); 1497be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = byterev_4(regs->gpr[rd]); 1498be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 14990016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1500c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras case 725: 1501c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras if (rb == 0) 1502c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras rb = 32; /* # bytes to store */ 1503c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->type = MKOP(STORE_MULTI, 0, rb); 1504c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->ea = 0; 1505c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras if (ra) 1506c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->ea = truncate_if_32bit(regs->msr, 1507c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras regs->gpr[ra]); 1508c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras break; 1509c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras 15100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 790: /* lhbrx */ 1511be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, BYTEREV, 2); 1512be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15140016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 918: /* sthbrx */ 1515be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, BYTEREV, 2); 1516be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = byterev_2(regs->gpr[rd]); 1517be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef CONFIG_VSX 15200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 844: /* lxvd2x */ 15210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 876: /* lxvd2ux */ 15220016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_VSX)) 1523be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto vsxunavail; 1524be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd | ((instr & 1) << 5); 1525be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD_VSX, u, 16); 1526be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 972: /* stxvd2x */ 15290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1004: /* stxvd2ux */ 15300016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_VSX)) 1531be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto vsxunavail; 1532be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->reg = rd | ((instr & 1) << 5); 1533be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE_VSX, u, 16); 1534be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15360016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif /* CONFIG_VSX */ 15370016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 15380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 15390016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15400016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 32: /* lwz */ 15410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 33: /* lwzu */ 1542be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, u, 4); 1543be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1544be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15450016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 34: /* lbz */ 15470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 35: /* lbzu */ 1548be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, u, 1); 1549be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1550be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15510016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15520016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 36: /* stw */ 15538e9f69371536981a2a8c9ee4a49dbe3aa4946df4Tiejun Chen case 37: /* stwu */ 1554be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, u, 4); 1555be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1556be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15578e9f69371536981a2a8c9ee4a49dbe3aa4946df4Tiejun Chen 15580016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 38: /* stb */ 15590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 39: /* stbu */ 1560be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, u, 1); 1561be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1562be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 40: /* lhz */ 15650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 41: /* lhzu */ 1566be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, u, 2); 1567be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1568be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15690016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15700016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 42: /* lha */ 15710016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 43: /* lhau */ 1572be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, SIGNEXT | u, 2); 1573be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1574be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15750016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15760016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 44: /* sth */ 15770016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 45: /* sthu */ 1578be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, u, 2); 1579be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1580be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15810016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15820016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 46: /* lmw */ 15830016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (ra >= rd) 15840016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; /* invalid form, ra in range to load */ 1585c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd)); 1586be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1587be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15880016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 15890016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 47: /* stmw */ 1590c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd)); 1591be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1592be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 15930016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 1594cd64d1697cf079bb8a67766e36e88ced38498933Sean MacLennan#ifdef CONFIG_PPC_FPU 15950016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 48: /* lfs */ 15960016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 49: /* lfsu */ 15970016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1598be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1599be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD_FP, u, 4); 1600be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1601be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16020016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16030016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 50: /* lfd */ 16040016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 51: /* lfdu */ 16050016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1606be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1607be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD_FP, u, 8); 1608be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1609be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16100016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16110016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 52: /* stfs */ 16120016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 53: /* stfsu */ 16130016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1614be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1615be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE_FP, u, 4); 1616be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1617be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16180016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16190016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 54: /* stfd */ 16200016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 55: /* stfdu */ 16210016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (!(regs->msr & MSR_FP)) 1622be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto fpunavail; 1623be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE_FP, u, 8); 1624be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dform_ea(instr, regs); 1625be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1626cd64d1697cf079bb8a67766e36e88ced38498933Sean MacLennan#endif 16270016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16280016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#ifdef __powerpc64__ 16290016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 58: /* ld[u], lwa */ 1630be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dsform_ea(instr, regs); 16310016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch (instr & 3) { 16320016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 0: /* ld */ 1633be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, 0, 8); 1634be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16350016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1: /* ldu */ 1636be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, UPDATE, 8); 1637be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16380016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 2: /* lwa */ 1639be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(LOAD, SIGNEXT, 4); 1640be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16410016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 16420016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 16430016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16440016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 62: /* std[u] */ 1645be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->ea = dsform_ea(instr, regs); 16460016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras switch (instr & 3) { 16470016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 0: /* std */ 1648be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, 0, 8); 1649be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16500016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras case 1: /* stdu */ 1651be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = MKOP(STORE, UPDATE, 8); 1652be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 16530016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 16540016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras break; 16550016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras#endif /* __powerpc64__ */ 16560016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16570016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras } 1658be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 16590016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16600016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras logical_done: 16610016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (instr & 1) 16620016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras set_cr0(regs, ra); 16630016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras goto instr_done; 16640016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras 16650016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras arith_done: 16660016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras if (instr & 1) 16670016a4cf5582415849fafbf9f019dd9530824789Paul Mackerras set_cr0(regs, rd); 1668be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1669be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras instr_done: 1670be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); 1671be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 1; 1672be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1673be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras priv: 1674be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = INTERRUPT | 0x700; 1675be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->val = SRR1_PROGPRIV; 1676be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1677be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1678cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras trap: 1679cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras op->type = INTERRUPT | 0x700; 1680cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras op->val = SRR1_PROGTRAP; 1681cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras return 0; 1682cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras 1683be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_PPC_FPU 1684be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras fpunavail: 1685be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = INTERRUPT | 0x800; 1686be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1687be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1688be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1689be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_ALTIVEC 1690be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras vecunavail: 1691be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = INTERRUPT | 0xf20; 1692be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1693be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1694be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1695be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_VSX 1696be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras vsxunavail: 1697be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op->type = INTERRUPT | 0xf40; 1698be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1699be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1700be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras} 1701be96f63375a14ee8e690856ac77e579c75bd0baePaul MackerrasEXPORT_SYMBOL_GPL(analyse_instr); 1702be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1703be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras/* 1704be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * For PPC32 we always use stwu with r1 to change the stack pointer. 1705be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * So this emulated store may corrupt the exception frame, now we 1706be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * have to provide the exception frame trampoline, which is pushed 1707be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * below the kprobed function stack. So we only update gpr[1] but 1708be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * don't emulate the real store operation. We will do real store 1709be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * operation safely in exception return code by checking this flag. 1710be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras */ 1711be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerrasstatic __kprobes int handle_stack_update(unsigned long ea, struct pt_regs *regs) 1712be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras{ 1713be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_PPC32 1714be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras /* 1715be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Check if we will touch kernel stack overflow 1716be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras */ 1717be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (ea - STACK_INT_FRAME_SIZE <= current->thread.ksp_limit) { 1718be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras printk(KERN_CRIT "Can't kprobe this since kernel stack would overflow.\n"); 1719be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return -EINVAL; 1720be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1721be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif /* CONFIG_PPC32 */ 1722be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras /* 1723be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Check if we already set since that means we'll 1724be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * lose the previous value. 1725be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras */ 1726be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras WARN_ON(test_thread_flag(TIF_EMULATE_STACK_STORE)); 1727be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras set_thread_flag(TIF_EMULATE_STACK_STORE); 1728be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1729be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras} 1730be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1731be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerrasstatic __kprobes void do_signext(unsigned long *valp, int size) 1732be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras{ 1733be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras switch (size) { 1734be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 2: 1735be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras *valp = (signed short) *valp; 1736be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1737be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 4: 1738be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras *valp = (signed int) *valp; 1739be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1740be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1741be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras} 1742be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1743be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerrasstatic __kprobes void do_byterev(unsigned long *valp, int size) 1744be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras{ 1745be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras switch (size) { 1746be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 2: 1747be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras *valp = byterev_2(*valp); 1748be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1749be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 4: 1750be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras *valp = byterev_4(*valp); 1751be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1752be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef __powerpc64__ 1753be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 8: 1754be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras *valp = byterev_8(*valp); 1755be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1756be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1757be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1758be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras} 1759be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1760be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras/* 1761be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Emulate instructions that cause a transfer of control, 1762be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * loads and stores, and a few other instructions. 1763be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * Returns 1 if the step was emulated, 0 if not, 1764be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * or -1 if the instruction is one that should not be stepped, 1765be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * such as an rfid, or a mtmsrd that would clear MSR_RI. 1766be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras */ 1767be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerrasint __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) 1768be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras{ 1769be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras struct instruction_op op; 1770be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras int r, err, size; 1771be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras unsigned long val; 1772be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras unsigned int cr; 1773c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras int i, rd, nb; 1774be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1775be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras r = analyse_instr(&op, regs, instr); 1776be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (r != 0) 1777be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return r; 1778be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1779be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = 0; 1780be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras size = GETSIZE(op.type); 1781be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras switch (op.type & INSTR_TYPE_MASK) { 1782be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case CACHEOP: 1783be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (!address_ok(regs, op.ea, 8)) 1784be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1785be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras switch (op.type & CACHEOP_MASK) { 1786be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case DCBST: 1787be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras __cacheop_user_asmx(op.ea, err, "dcbst"); 1788be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1789be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case DCBF: 1790be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras __cacheop_user_asmx(op.ea, err, "dcbf"); 1791be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1792be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case DCBTST: 1793be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (op.reg == 0) 1794be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras prefetchw((void *) op.ea); 1795be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1796be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case DCBT: 1797be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (op.reg == 0) 1798be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras prefetch((void *) op.ea); 1799be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1800cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras case ICBI: 1801cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras __cacheop_user_asmx(op.ea, err, "icbi"); 1802cf87c3f6b64791ce5d4c7e591c915065d31a162dPaul Mackerras break; 1803be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1804be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (err) 1805be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1806be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto instr_done; 1807be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1808be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case LARX: 1809be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1810be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1811be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (op.ea & (size - 1)) 1812be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; /* can't handle misaligned */ 1813be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = -EFAULT; 1814be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (!address_ok(regs, op.ea, size)) 1815be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1816be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = 0; 1817be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras switch (size) { 1818be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 4: 1819be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras __get_user_asmx(val, op.ea, err, "lwarx"); 1820be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1821be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 8: 1822be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras __get_user_asmx(val, op.ea, err, "ldarx"); 1823be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1824be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras default: 1825be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1826be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1827be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (!err) 1828be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[op.reg] = val; 1829be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1830be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1831be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case STCX: 1832be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1833be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1834be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (op.ea & (size - 1)) 1835be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; /* can't handle misaligned */ 1836be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = -EFAULT; 1837be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (!address_ok(regs, op.ea, size)) 1838be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1839be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = 0; 1840be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras switch (size) { 1841be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 4: 1842be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras __put_user_asmx(op.val, op.ea, err, "stwcx.", cr); 1843be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1844be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case 8: 1845be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras __put_user_asmx(op.val, op.ea, err, "stdcx.", cr); 1846be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras break; 1847be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras default: 1848be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1849be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1850be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (!err) 1851be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->ccr = (regs->ccr & 0x0fffffff) | 1852be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras (cr & 0xe0000000) | 1853be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras ((regs->xer >> 3) & 0x10000000); 1854be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1855be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1856be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case LOAD: 1857be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1858be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1859be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = read_mem(®s->gpr[op.reg], op.ea, size, regs); 1860be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (!err) { 1861be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (op.type & SIGNEXT) 1862be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras do_signext(®s->gpr[op.reg], size); 1863be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (op.type & BYTEREV) 1864be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras do_byterev(®s->gpr[op.reg], size); 1865be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1866be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1867be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1868be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case LOAD_FP: 1869be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1870be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1871be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (size == 4) 1872be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_fp_load(op.reg, do_lfs, op.ea, size, regs); 1873be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras else 1874be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_fp_load(op.reg, do_lfd, op.ea, size, regs); 1875be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1876be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1877be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_ALTIVEC 1878be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case LOAD_VMX: 1879be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1880be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1881be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_vec_load(op.reg, do_lvx, op.ea & ~0xfUL, regs); 1882be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1883be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1884be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_VSX 1885be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case LOAD_VSX: 1886be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1887be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1888be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_vsx_load(op.reg, do_lxvd2x, op.ea, regs); 1889be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1890be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1891be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case LOAD_MULTI: 1892be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1893be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1894be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras rd = op.reg; 1895c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras for (i = 0; i < size; i += 4) { 1896c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras nb = size - i; 1897c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras if (nb > 4) 1898c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras nb = 4; 1899c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras err = read_mem(®s->gpr[rd], op.ea, nb, regs); 1900be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (err) 1901be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1902c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras if (nb < 4) /* left-justify last bytes */ 1903c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras regs->gpr[rd] <<= 32 - 8 * nb; 1904be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op.ea += 4; 1905c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras ++rd; 1906c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras } 1907be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto instr_done; 1908be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1909be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case STORE: 1910be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1911be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1912be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if ((op.type & UPDATE) && size == sizeof(long) && 1913be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op.reg == 1 && op.update_reg == 1 && 1914be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras !(regs->msr & MSR_PR) && 1915be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op.ea >= regs->gpr[1] - STACK_INT_FRAME_SIZE) { 1916be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = handle_stack_update(op.ea, regs); 1917be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1918be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1919be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = write_mem(op.val, op.ea, size, regs); 1920be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1921be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1922be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case STORE_FP: 1923be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1924be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1925be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (size == 4) 1926be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_fp_store(op.reg, do_stfs, op.ea, size, regs); 1927be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras else 1928be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_fp_store(op.reg, do_stfd, op.ea, size, regs); 1929be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1930be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1931be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_ALTIVEC 1932be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case STORE_VMX: 1933be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1934be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1935be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs); 1936be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1937be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1938be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_VSX 1939be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case STORE_VSX: 1940be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1941be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1942be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras err = do_vsx_store(op.reg, do_stxvd2x, op.ea, regs); 1943be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto ldst_done; 1944be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 1945be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case STORE_MULTI: 1946be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->msr & MSR_LE) 1947be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1948be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras rd = op.reg; 1949c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras for (i = 0; i < size; i += 4) { 1950c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras val = regs->gpr[rd]; 1951c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras nb = size - i; 1952c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras if (nb > 4) 1953c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras nb = 4; 1954c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras else 1955c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras val >>= 32 - 8 * nb; 1956c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras err = write_mem(val, op.ea, nb, regs); 1957be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (err) 1958be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 1959be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras op.ea += 4; 1960c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras ++rd; 1961c9f6f4ed95d47e3319dedaf8cc31d744ac67fe6fPaul Mackerras } 1962be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto instr_done; 1963be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1964be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case MFMSR: 1965be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[op.reg] = regs->msr & MSR_MASK; 1966be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto instr_done; 1967be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1968be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case MTMSR: 1969be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras val = regs->gpr[op.reg]; 1970be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if ((val & MSR_RI) == 0) 1971be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras /* can't step mtmsr[d] that would clear MSR_RI */ 1972be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return -1; 1973be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras /* here op.val is the mask of bits to change */ 1974be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->msr = (regs->msr & ~op.val) | (val & op.val); 1975be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto instr_done; 1976be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1977be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#ifdef CONFIG_PPC64 1978be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case SYSCALL: /* sc */ 1979be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras /* 1980be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * N.B. this uses knowledge about how the syscall 1981be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * entry code works. If that is changed, this will 1982be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras * need to be changed also. 1983be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras */ 1984be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (regs->gpr[0] == 0x1ebe && 1985be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras cpu_has_feature(CPU_FTR_REAL_LE)) { 1986be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->msr ^= MSR_LE; 1987be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras goto instr_done; 1988be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 1989be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[9] = regs->gpr[13]; 1990be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[10] = MSR_KERNEL; 1991be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[11] = regs->nip + 4; 1992be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[12] = regs->msr & MSR_MASK; 1993be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[13] = (unsigned long) get_paca(); 1994be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->nip = (unsigned long) &system_call_common; 1995be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->msr = MSR_KERNEL; 1996be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 1; 1997be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 1998be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras case RFI: 1999be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return -1; 2000be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras#endif 2001be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras } 2002be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 2003be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 2004be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras ldst_done: 2005be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (err) 2006be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 0; 2007be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras if (op.type & UPDATE) 2008be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->gpr[op.update_reg] = op.ea; 2009be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras 2010be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras instr_done: 2011be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); 2012be96f63375a14ee8e690856ac77e579c75bd0baePaul Mackerras return 1; 201314cf11af6cf608eb8c23e989ddb17a715ddce109Paul Mackerras} 2014