10c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* visemul.c: Emulation of VIS instructions. 20c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller * 30c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller * Copyright (C) 2006 David S. Miller (davem@davemloft.net) 40c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller */ 50c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#include <linux/kernel.h> 60c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#include <linux/errno.h> 70c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#include <linux/thread_info.h> 8121dd5f2776522e03970916514b46e355480e538David S. Miller#include <linux/perf_event.h> 90c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#include <asm/ptrace.h> 110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#include <asm/pstate.h> 120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#include <asm/fpumacro.h> 130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#include <asm/uaccess.h> 14d550bbd40c0e10aefa05103dadbe0ae42e683707David Howells#include <asm/cacheflush.h> 150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* OPF field of various VIS instructions. */ 170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000111011 - four 16-bit packs */ 190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FPACK16_OPF 0x03b 200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000111010 - two 32-bit packs */ 220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FPACK32_OPF 0x03a 230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000111101 - four 16-bit packs */ 250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FPACKFIX_OPF 0x03d 260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 001001101 - four 16-bit expands */ 280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FEXPAND_OPF 0x04d 290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 001001011 - two 32-bit merges */ 310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FPMERGE_OPF 0x04b 320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000110001 - 8-by-16-bit partitoned product */ 340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FMUL8x16_OPF 0x031 350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000110011 - 8-by-16-bit upper alpha partitioned product */ 370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FMUL8x16AU_OPF 0x033 380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000110101 - 8-by-16-bit lower alpha partitioned product */ 400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FMUL8x16AL_OPF 0x035 410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000110110 - upper 8-by-16-bit partitioned product */ 430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FMUL8SUx16_OPF 0x036 440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000110111 - lower 8-by-16-bit partitioned product */ 460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FMUL8ULx16_OPF 0x037 470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000111000 - upper 8-by-16-bit partitioned product */ 490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FMULD8SUx16_OPF 0x038 500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000111001 - lower unsigned 8-by-16-bit partitioned product */ 520c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FMULD8ULx16_OPF 0x039 530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000101000 - four 16-bit compare; set rd if src1 > src2 */ 550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPGT16_OPF 0x028 560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000101100 - two 32-bit compare; set rd if src1 > src2 */ 580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPGT32_OPF 0x02c 590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000100000 - four 16-bit compare; set rd if src1 <= src2 */ 610c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPLE16_OPF 0x020 620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000100100 - two 32-bit compare; set rd if src1 <= src2 */ 640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPLE32_OPF 0x024 650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000100010 - four 16-bit compare; set rd if src1 != src2 */ 670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPNE16_OPF 0x022 680c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000100110 - two 32-bit compare; set rd if src1 != src2 */ 700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPNE32_OPF 0x026 710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000101010 - four 16-bit compare; set rd if src1 == src2 */ 730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPEQ16_OPF 0x02a 740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000101110 - two 32-bit compare; set rd if src1 == src2 */ 760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define FCMPEQ32_OPF 0x02e 770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 780c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000000 - Eight 8-bit edge boundary processing */ 790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE8_OPF 0x000 800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000001 - Eight 8-bit edge boundary processing, no CC */ 820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE8N_OPF 0x001 830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000010 - Eight 8-bit edge boundary processing, little-endian */ 850c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE8L_OPF 0x002 860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000011 - Eight 8-bit edge boundary processing, little-endian, no CC */ 880c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE8LN_OPF 0x003 890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000100 - Four 16-bit edge boundary processing */ 910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE16_OPF 0x004 920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000101 - Four 16-bit edge boundary processing, no CC */ 940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE16N_OPF 0x005 950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000110 - Four 16-bit edge boundary processing, little-endian */ 970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE16L_OPF 0x006 980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000000111 - Four 16-bit edge boundary processing, little-endian, no CC */ 1000c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE16LN_OPF 0x007 1010c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000001000 - Two 32-bit edge boundary processing */ 1030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE32_OPF 0x008 1040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000001001 - Two 32-bit edge boundary processing, no CC */ 1060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE32N_OPF 0x009 1070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000001010 - Two 32-bit edge boundary processing, little-endian */ 1090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE32L_OPF 0x00a 1100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000001011 - Two 32-bit edge boundary processing, little-endian, no CC */ 1120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define EDGE32LN_OPF 0x00b 1130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000111110 - distance between 8 8-bit components */ 1150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define PDIST_OPF 0x03e 1160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000010000 - convert 8-bit 3-D address to blocked byte address */ 1180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define ARRAY8_OPF 0x010 1190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000010010 - convert 16-bit 3-D address to blocked byte address */ 1210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define ARRAY16_OPF 0x012 1220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000010100 - convert 32-bit 3-D address to blocked byte address */ 1240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define ARRAY32_OPF 0x014 1250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 000011001 - Set the GSR.MASK field in preparation for a BSHUFFLE */ 1270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define BMASK_OPF 0x019 1280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* 001001100 - Permute bytes as specified by GSR.MASK */ 1300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define BSHUFFLE_OPF 0x04c 1310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define VIS_OPF_SHIFT 5 1330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define VIS_OPF_MASK (0x1ff << VIS_OPF_SHIFT) 1340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 135726c12f57d7e3ff43693d88e13b1ff02464c75d3Joseph Myers#define RS1(INSN) (((INSN) >> 14) & 0x1f) 1360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define RS2(INSN) (((INSN) >> 0) & 0x1f) 1370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller#define RD(INSN) (((INSN) >> 25) & 0x1f) 1380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, 1400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int rd, int from_kernel) 1410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 1420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (rs2 >= 16 || rs1 >= 16 || rd >= 16) { 1430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (from_kernel != 0) 1440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller __asm__ __volatile__("flushw"); 1450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller else 1460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller flushw_user(); 1470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 1480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 1490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) 1510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 152517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller unsigned long value, fp; 1530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (reg < 16) 1550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return (!reg ? 0 : regs->u_regs[reg]); 156517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller 157517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller fp = regs->u_regs[UREG_FP]; 158517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller 1590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (regs->tstate & TSTATE_PRIV) { 1600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct reg_window *win; 161517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller win = (struct reg_window *)(fp + STACK_BIAS); 1620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller value = win->locals[reg - 16]; 163517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller } else if (!test_thread_64bit_stack(fp)) { 1640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct reg_window32 __user *win32; 165517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); 1660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller get_user(value, &win32->locals[reg - 16]); 1670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } else { 1680c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct reg_window __user *win; 169517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller win = (struct reg_window __user *)(fp + STACK_BIAS); 1700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller get_user(value, &win->locals[reg - 16]); 1710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 1720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return value; 1730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 1740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, 1760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct pt_regs *regs) 1770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 178517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller unsigned long fp = regs->u_regs[UREG_FP]; 179517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller 1800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller BUG_ON(reg < 16); 1810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller BUG_ON(regs->tstate & TSTATE_PRIV); 1820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 183517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller if (!test_thread_64bit_stack(fp)) { 1840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct reg_window32 __user *win32; 185517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); 1860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return (unsigned long __user *)&win32->locals[reg - 16]; 1870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } else { 1880c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct reg_window __user *win; 189517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller win = (struct reg_window __user *)(fp + STACK_BIAS); 1900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return &win->locals[reg - 16]; 1910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 1920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 1930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 1940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic inline unsigned long *__fetch_reg_addr_kern(unsigned int reg, 1950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct pt_regs *regs) 1960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 1970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller BUG_ON(reg >= 16); 1980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller BUG_ON(regs->tstate & TSTATE_PRIV); 1990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2000c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return ®s->u_regs[reg]; 2010c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 2020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) 2040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 2050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (rd < 16) { 2060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long *rd_kern = __fetch_reg_addr_kern(rd, regs); 2070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *rd_kern = val; 2090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } else { 2100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); 2110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 212517ffce4e1a03aea979fe3a18a3dd1761a24fafbDavid S. Miller if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) 2130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller __put_user((u32)val, (u32 __user *)rd_user); 2140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller else 2150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller __put_user(val, rd_user); 2160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 2170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 2180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic inline unsigned long fpd_regval(struct fpustate *f, 2200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int insn_regnum) 2210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 2220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller insn_regnum = (((insn_regnum & 1) << 5) | 2230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (insn_regnum & 0x1e)); 2240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return *(unsigned long *) &f->regs[insn_regnum]; 2260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 2270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic inline unsigned long *fpd_regaddr(struct fpustate *f, 2290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int insn_regnum) 2300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 2310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller insn_regnum = (((insn_regnum & 1) << 5) | 2320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (insn_regnum & 0x1e)); 2330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return (unsigned long *) &f->regs[insn_regnum]; 2350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 2360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic inline unsigned int fps_regval(struct fpustate *f, 2380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int insn_regnum) 2390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 2400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return f->regs[insn_regnum]; 2410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 2420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic inline unsigned int *fps_regaddr(struct fpustate *f, 2440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int insn_regnum) 2450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 2460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return &f->regs[insn_regnum]; 2470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 2480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstruct edge_tab { 2500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 left, right; 2510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller}; 2527e0b1e6186c755becf8b19c844c63db1a551898bDavid S. Millerstatic struct edge_tab edge8_tab[8] = { 2530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xff, 0x80 }, 2540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x7f, 0xc0 }, 2550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x3f, 0xe0 }, 2560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x1f, 0xf0 }, 2570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x0f, 0xf8 }, 2580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x07, 0xfc }, 2590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x03, 0xfe }, 2600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x01, 0xff }, 2610c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller}; 2627e0b1e6186c755becf8b19c844c63db1a551898bDavid S. Millerstatic struct edge_tab edge8_tab_l[8] = { 2630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xff, 0x01 }, 2640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xfe, 0x03 }, 2650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xfc, 0x07 }, 2660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xf8, 0x0f }, 2670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xf0, 0x1f }, 2680c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xe0, 0x3f }, 2690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xc0, 0x7f }, 2700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x80, 0xff }, 2710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller}; 2727e0b1e6186c755becf8b19c844c63db1a551898bDavid S. Millerstatic struct edge_tab edge16_tab[4] = { 2730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xf, 0x8 }, 2740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x7, 0xc }, 2750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x3, 0xe }, 2760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x1, 0xf }, 2770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller}; 2787e0b1e6186c755becf8b19c844c63db1a551898bDavid S. Millerstatic struct edge_tab edge16_tab_l[4] = { 2790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xf, 0x1 }, 2800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xe, 0x3 }, 2810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0xc, 0x7 }, 2820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x8, 0xf }, 2830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller}; 2847e0b1e6186c755becf8b19c844c63db1a551898bDavid S. Millerstatic struct edge_tab edge32_tab[2] = { 2850c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x3, 0x2 }, 2860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x1, 0x3 }, 2870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller}; 2887e0b1e6186c755becf8b19c844c63db1a551898bDavid S. Millerstatic struct edge_tab edge32_tab_l[2] = { 2890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x3, 0x1 }, 2900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller { 0x2, 0x3 }, 2910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller}; 2920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void edge(struct pt_regs *regs, unsigned int insn, unsigned int opf) 2940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 2950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long orig_rs1, rs1, orig_rs2, rs2, rd_val; 2960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 left, right; 2970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 2980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller maybe_flush_windows(RS1(insn), RS2(insn), RD(insn), 0); 2990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller orig_rs1 = rs1 = fetch_reg(RS1(insn), regs); 3000c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller orig_rs2 = rs2 = fetch_reg(RS2(insn), regs); 3010c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (test_thread_flag(TIF_32BIT)) { 3030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = rs1 & 0xffffffff; 3040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = rs2 & 0xffffffff; 3050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 3060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller switch (opf) { 3070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller default: 3080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8_OPF: 3090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8N_OPF: 3100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller left = edge8_tab[rs1 & 0x7].left; 3110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller right = edge8_tab[rs2 & 0x7].right; 3120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 3130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8L_OPF: 3140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8LN_OPF: 3150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller left = edge8_tab_l[rs1 & 0x7].left; 3160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller right = edge8_tab_l[rs2 & 0x7].right; 3170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 3180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16_OPF: 3200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16N_OPF: 3210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller left = edge16_tab[(rs1 >> 1) & 0x3].left; 3220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller right = edge16_tab[(rs2 >> 1) & 0x3].right; 3230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 3240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16L_OPF: 3260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16LN_OPF: 3270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller left = edge16_tab_l[(rs1 >> 1) & 0x3].left; 3280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller right = edge16_tab_l[(rs2 >> 1) & 0x3].right; 3290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 3300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32_OPF: 3320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32N_OPF: 3330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller left = edge32_tab[(rs1 >> 2) & 0x1].left; 3340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller right = edge32_tab[(rs2 >> 2) & 0x1].right; 3350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 3360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32L_OPF: 3380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32LN_OPF: 3390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller left = edge32_tab_l[(rs1 >> 2) & 0x1].left; 3400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller right = edge32_tab_l[(rs2 >> 2) & 0x1].right; 3410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 3426cb79b3f3ba2b14590cac02ee13ab7410b6225edJoe Perches } 3430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if ((rs1 & ~0x7UL) == (rs2 & ~0x7UL)) 3450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = right & left; 3460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller else 3470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = left; 3480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller store_reg(regs, rd_val, RD(insn)); 3500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller switch (opf) { 3520c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8_OPF: 3530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8L_OPF: 3540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16_OPF: 3550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16L_OPF: 3560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32_OPF: 3570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32L_OPF: { 3580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long ccr, tstate; 3590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller __asm__ __volatile__("subcc %1, %2, %%g0\n\t" 3610c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller "rd %%ccr, %0" 3620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller : "=r" (ccr) 3630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller : "r" (orig_rs1), "r" (orig_rs2) 3640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller : "cc"); 3650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller tstate = regs->tstate & ~(TSTATE_XCC | TSTATE_ICC); 3660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller regs->tstate = tstate | (ccr << 32UL); 3670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 3686cb79b3f3ba2b14590cac02ee13ab7410b6225edJoe Perches } 3690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 3700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void array(struct pt_regs *regs, unsigned int insn, unsigned int opf) 3720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 3730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long rs1, rs2, rd_val; 3740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int bits, bits_mask; 3750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller maybe_flush_windows(RS1(insn), RS2(insn), RD(insn), 0); 3770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fetch_reg(RS1(insn), regs); 3780c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fetch_reg(RS2(insn), regs); 3790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller bits = (rs2 > 5 ? 5 : rs2); 3810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller bits_mask = (1UL << bits) - 1UL; 3820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = ((((rs1 >> 11) & 0x3) << 0) | 3840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 33) & 0x3) << 2) | 3850c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 55) & 0x1) << 4) | 3860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 13) & 0xf) << 5) | 3870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 35) & 0xf) << 9) | 3880c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 56) & 0xf) << 13) | 3890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 17) & bits_mask) << 17) | 3900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 39) & bits_mask) << (17 + bits)) | 3910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (((rs1 >> 60) & 0xf) << (17 + (2*bits)))); 3920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller switch (opf) { 3940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case ARRAY16_OPF: 3950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val <<= 1; 3960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 3970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 3980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case ARRAY32_OPF: 3990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val <<= 2; 4006cb79b3f3ba2b14590cac02ee13ab7410b6225edJoe Perches } 4010c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller store_reg(regs, rd_val, RD(insn)); 4030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 4040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void bmask(struct pt_regs *regs, unsigned int insn) 4060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 4070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long rs1, rs2, rd_val, gsr; 4080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller maybe_flush_windows(RS1(insn), RS2(insn), RD(insn), 0); 4100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fetch_reg(RS1(insn), regs); 4110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fetch_reg(RS2(insn), regs); 4120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = rs1 + rs2; 4130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller store_reg(regs, rd_val, RD(insn)); 4150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller gsr = current_thread_info()->gsr[0] & 0xffffffff; 4170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller gsr |= rd_val << 32UL; 4180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller current_thread_info()->gsr[0] = gsr; 4190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 4200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void bshuffle(struct pt_regs *regs, unsigned int insn) 4220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 4230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct fpustate *f = FPUSTATE; 4240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long rs1, rs2, rd_val; 4250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long bmask, i; 4260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller bmask = current_thread_info()->gsr[0] >> 32UL; 4280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fpd_regval(f, RS1(insn)); 4300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fpd_regval(f, RS2(insn)); 4310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0UL; 4330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 8; i++) { 4340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long which = (bmask >> (i * 4)) & 0xf; 4350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long byte; 4360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (which < 8) 4380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller byte = (rs1 >> (which * 8)) & 0xff; 4390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller else 4400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller byte = (rs2 >> ((which-8)*8)) & 0xff; 4410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= (byte << (i * 8)); 4420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 4430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 4450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 4460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void pdist(struct pt_regs *regs, unsigned int insn) 4480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 4490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct fpustate *f = FPUSTATE; 4500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long rs1, rs2, *rd, rd_val; 4510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long i; 4520c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fpd_regval(f, RS1(insn)); 454726c12f57d7e3ff43693d88e13b1ff02464c75d3Joseph Myers rs2 = fpd_regval(f, RS2(insn)); 4550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd = fpd_regaddr(f, RD(insn)); 4560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = *rd; 4580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 8; i++) { 4600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 s1, s2; 4610c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s1 = (rs1 >> (56 - (i * 8))) & 0xff; 4630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s2 = (rs2 >> (56 - (i * 8))) & 0xff; 4640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Absolute value of difference. */ 4660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s1 -= s2; 4670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (s1 < 0) 4680c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s1 = ~s1 + 1; 4690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val += s1; 4710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 4720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *rd = rd_val; 4740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 4750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void pformat(struct pt_regs *regs, unsigned int insn, unsigned int opf) 4770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 4780c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct fpustate *f = FPUSTATE; 4790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long rs1, rs2, gsr, scale, rd_val; 4800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller gsr = current_thread_info()->gsr[0]; 4820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller scale = (gsr >> 3) & (opf == FPACK16_OPF ? 0xf : 0x1f); 4830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller switch (opf) { 4840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPACK16_OPF: { 4850c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long byte; 4860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fpd_regval(f, RS2(insn)); 4880c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 4890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (byte = 0; byte < 4; byte++) { 4900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int val; 4910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 src = (rs2 >> (byte * 16UL)) & 0xffffUL; 4920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller int scaled = src << scale; 4930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller int from_fixed = scaled >> 7; 4940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 4950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller val = ((from_fixed < 0) ? 4960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 0 : 4970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (from_fixed > 255) ? 4980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 255 : from_fixed); 4990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5000c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= (val << (8 * byte)); 5010c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fps_regaddr(f, RD(insn)) = rd_val; 5030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 5040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPACK32_OPF: { 5070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long word; 5080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fpd_regval(f, RS1(insn)); 5100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fpd_regval(f, RS2(insn)); 5110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = (rs1 << 8) & ~(0x000000ff000000ffUL); 5120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (word = 0; word < 2; word++) { 5130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long val; 5140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s32 src = (rs2 >> (word * 32UL)); 5150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s64 scaled = src << scale; 5160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s64 from_fixed = scaled >> 23; 5170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller val = ((from_fixed < 0) ? 5190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 0 : 5200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (from_fixed > 255) ? 5210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 255 : from_fixed); 5220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= (val << (32 * word)); 5240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 5260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 5270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPACKFIX_OPF: { 5300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long word; 5310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fpd_regval(f, RS2(insn)); 5330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 5350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (word = 0; word < 2; word++) { 5360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller long val; 5370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s32 src = (rs2 >> (word * 32UL)); 5380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s64 scaled = src << scale; 5390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s64 from_fixed = scaled >> 16; 5400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller val = ((from_fixed < -32768) ? 5420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller -32768 : 5430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller (from_fixed > 32767) ? 5440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 32767 : from_fixed); 5450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= ((val & 0xffff) << (word * 16)); 5470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fps_regaddr(f, RD(insn)) = rd_val; 5490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 5500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5520c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FEXPAND_OPF: { 5530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long byte; 5540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fps_regval(f, RS2(insn)); 5560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 5580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (byte = 0; byte < 4; byte++) { 5590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long val; 5600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u8 src = (rs2 >> (byte * 8)) & 0xff; 5610c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller val = src << 4; 5630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= (val << (byte * 16)); 5650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 5670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 5680c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPMERGE_OPF: { 5710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fps_regval(f, RS1(insn)); 5720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fps_regval(f, RS2(insn)); 5730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = (((rs2 & 0x000000ff) << 0) | 5750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((rs1 & 0x000000ff) << 8) | 5760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((rs2 & 0x0000ff00) << 8) | 5770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((rs1 & 0x0000ff00) << 16) | 5780c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((rs2 & 0x00ff0000) << 16) | 5790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((rs1 & 0x00ff0000) << 24) | 5800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((rs2 & 0xff000000) << 24) | 5810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((rs1 & 0xff000000) << 32)); 5820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 5830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 5840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 5856cb79b3f3ba2b14590cac02ee13ab7410b6225edJoe Perches } 5860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 5870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5880c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void pmul(struct pt_regs *regs, unsigned int insn, unsigned int opf) 5890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 5900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct fpustate *f = FPUSTATE; 5910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long rs1, rs2, rd_val; 5920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller switch (opf) { 5940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8x16_OPF: { 5950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long byte; 5960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 5970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fps_regval(f, RS1(insn)); 5980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fpd_regval(f, RS2(insn)); 5990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6000c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 6010c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (byte = 0; byte < 4; byte++) { 6020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 src1 = (rs1 >> (byte * 8)) & 0x00ff; 6030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 src2 = (rs2 >> (byte * 16)) & 0xffff; 6040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u32 prod = src1 * src2; 6050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 scaled = ((prod & 0x00ffff00) >> 8); 6060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Round up. */ 6080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (prod & 0x80) 6090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller scaled++; 6100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= ((scaled & 0xffffUL) << (byte * 16UL)); 6110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 6120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 6140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 6150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 6160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8x16AU_OPF: 6180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8x16AL_OPF: { 6190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long byte; 6200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 src2; 6210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fps_regval(f, RS1(insn)); 6230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fps_regval(f, RS2(insn)); 6240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 62688b938e63e68fd35e603421f722be0f35dde1016Roel Kluin src2 = rs2 >> (opf == FMUL8x16AU_OPF ? 16 : 0); 6270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (byte = 0; byte < 4; byte++) { 6280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 src1 = (rs1 >> (byte * 8)) & 0x00ff; 6290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u32 prod = src1 * src2; 6300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 scaled = ((prod & 0x00ffff00) >> 8); 6310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Round up. */ 6330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (prod & 0x80) 6340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller scaled++; 6350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= ((scaled & 0xffffUL) << (byte * 16UL)); 6360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 6370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 6390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 6400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 6410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8SUx16_OPF: 6430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8ULx16_OPF: { 6440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long byte, ushift; 6450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fpd_regval(f, RS1(insn)); 6470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fpd_regval(f, RS2(insn)); 6480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 6500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ushift = (opf == FMUL8SUx16_OPF) ? 8 : 0; 6510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (byte = 0; byte < 4; byte++) { 6520c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 src1; 6530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 src2; 6540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u32 prod; 6550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 scaled; 6560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller src1 = ((rs1 >> ((16 * byte) + ushift)) & 0x00ff); 6580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller src2 = ((rs2 >> (16 * byte)) & 0xffff); 6590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller prod = src1 * src2; 6600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller scaled = ((prod & 0x00ffff00) >> 8); 6610c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Round up. */ 6630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (prod & 0x80) 6640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller scaled++; 6650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= ((scaled & 0xffffUL) << (byte * 16UL)); 6660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 6670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6680c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 6690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 6700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 6710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMULD8SUx16_OPF: 6730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMULD8ULx16_OPF: { 6740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long byte, ushift; 6750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fps_regval(f, RS1(insn)); 6770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fps_regval(f, RS2(insn)); 6780c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 6800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ushift = (opf == FMULD8SUx16_OPF) ? 8 : 0; 6810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (byte = 0; byte < 2; byte++) { 6820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 src1; 6830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 src2; 6840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u32 prod; 6850c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller u16 scaled; 6860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller src1 = ((rs1 >> ((16 * byte) + ushift)) & 0x00ff); 6880c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller src2 = ((rs2 >> (16 * byte)) & 0xffff); 6890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller prod = src1 * src2; 6900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller scaled = ((prod & 0x00ffff00) >> 8); 6910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 6920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Round up. */ 6930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (prod & 0x80) 6940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller scaled++; 6950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val |= ((scaled & 0xffffUL) << 6960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller ((byte * 32UL) + 7UL)); 6970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 6980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller *fpd_regaddr(f, RD(insn)) = rd_val; 6990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7000c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7016cb79b3f3ba2b14590cac02ee13ab7410b6225edJoe Perches } 7020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 7030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerstatic void pcmp(struct pt_regs *regs, unsigned int insn, unsigned int opf) 7050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 7060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller struct fpustate *f = FPUSTATE; 7070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long rs1, rs2, rd_val, i; 7080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs1 = fpd_regval(f, RS1(insn)); 7100c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rs2 = fpd_regval(f, RS2(insn)); 7110c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller rd_val = 0; 7130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller switch (opf) { 7150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPGT16_OPF: 7160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 4; i++) { 7170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 a = (rs1 >> (i * 16)) & 0xffff; 7180c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 b = (rs2 >> (i * 16)) & 0xffff; 7190c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a > b) 7212e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 8 >> i; 7220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPGT32_OPF: 7260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 2; i++) { 7272e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 a = (rs1 >> (i * 32)) & 0xffffffff; 7282e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 b = (rs2 >> (i * 32)) & 0xffffffff; 7290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a > b) 7312e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 2 >> i; 7320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPLE16_OPF: 7360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 4; i++) { 7370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 a = (rs1 >> (i * 16)) & 0xffff; 7380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 b = (rs2 >> (i * 16)) & 0xffff; 7390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a <= b) 7412e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 8 >> i; 7420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPLE32_OPF: 7460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 2; i++) { 7472e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 a = (rs1 >> (i * 32)) & 0xffffffff; 7482e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 b = (rs2 >> (i * 32)) & 0xffffffff; 7490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a <= b) 7512e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 2 >> i; 7520c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPNE16_OPF: 7560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 4; i++) { 7570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 a = (rs1 >> (i * 16)) & 0xffff; 7580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 b = (rs2 >> (i * 16)) & 0xffff; 7590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a != b) 7612e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 8 >> i; 7620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPNE32_OPF: 7660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 2; i++) { 7672e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 a = (rs1 >> (i * 32)) & 0xffffffff; 7682e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 b = (rs2 >> (i * 32)) & 0xffffffff; 7690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a != b) 7712e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 2 >> i; 7720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPEQ16_OPF: 7760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 4; i++) { 7770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 a = (rs1 >> (i * 16)) & 0xffff; 7780c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller s16 b = (rs2 >> (i * 16)) & 0xffff; 7790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a == b) 7812e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 8 >> i; 7820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7850c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPEQ32_OPF: 7860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller for (i = 0; i < 2; i++) { 7872e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 a = (rs1 >> (i * 32)) & 0xffffffff; 7882e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller s32 b = (rs2 >> (i * 32)) & 0xffffffff; 7890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (a == b) 7912e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92David S. Miller rd_val |= 2 >> i; 7920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller } 7930c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 7946cb79b3f3ba2b14590cac02ee13ab7410b6225edJoe Perches } 7950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 7960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller maybe_flush_windows(0, 0, RD(insn), 0); 7970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller store_reg(regs, rd_val, RD(insn)); 7980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 7990c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8000c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller/* Emulate the VIS instructions which are not implemented in 8010c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller * hardware on Niagara. 8020c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller */ 8030c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Millerint vis_emul(struct pt_regs *regs, unsigned int insn) 8040c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller{ 8050c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned long pc = regs->tpc; 8060c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller unsigned int opf; 8070c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8080c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller BUG_ON(regs->tstate & TSTATE_PRIV); 8090c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 810a8b0ca17b80e92faab46ee7179ba9e99ccb61233Peter Zijlstra perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); 811121dd5f2776522e03970916514b46e355480e538David S. Miller 8120c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (test_thread_flag(TIF_32BIT)) 8130c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller pc = (u32)pc; 8140c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8150c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller if (get_user(insn, (u32 __user *) pc)) 8160c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return -EFAULT; 8170c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 818410d2c8187ed969238ba98008c1d57307a56cfd8Hong H. Pham save_and_clear_fpu(); 819410d2c8187ed969238ba98008c1d57307a56cfd8Hong H. Pham 8200c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller opf = (insn & VIS_OPF_MASK) >> VIS_OPF_SHIFT; 8210c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller switch (opf) { 8220c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller default: 8230c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return -EINVAL; 8240c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8250c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Pixel Formatting Instructions. */ 8260c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPACK16_OPF: 8270c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPACK32_OPF: 8280c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPACKFIX_OPF: 8290c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FEXPAND_OPF: 8300c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FPMERGE_OPF: 8310c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller pformat(regs, insn, opf); 8320c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8330c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8340c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Partitioned Multiply Instructions */ 8350c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8x16_OPF: 8360c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8x16AU_OPF: 8370c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8x16AL_OPF: 8380c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8SUx16_OPF: 8390c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMUL8ULx16_OPF: 8400c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMULD8SUx16_OPF: 8410c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FMULD8ULx16_OPF: 8420c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller pmul(regs, insn, opf); 8430c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8440c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8450c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Pixel Compare Instructions */ 8460c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPGT16_OPF: 8470c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPGT32_OPF: 8480c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPLE16_OPF: 8490c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPLE32_OPF: 8500c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPNE16_OPF: 8510c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPNE32_OPF: 8520c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPEQ16_OPF: 8530c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case FCMPEQ32_OPF: 8540c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller pcmp(regs, insn, opf); 8550c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8560c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8570c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Edge Handling Instructions */ 8580c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8_OPF: 8590c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8N_OPF: 8600c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8L_OPF: 8610c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE8LN_OPF: 8620c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16_OPF: 8630c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16N_OPF: 8640c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16L_OPF: 8650c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE16LN_OPF: 8660c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32_OPF: 8670c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32N_OPF: 8680c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32L_OPF: 8690c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case EDGE32LN_OPF: 8700c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller edge(regs, insn, opf); 8710c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8720c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8730c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Pixel Component Distance */ 8740c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case PDIST_OPF: 8750c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller pdist(regs, insn); 8760c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8770c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8780c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Three-Dimensional Array Addressing Instructions */ 8790c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case ARRAY8_OPF: 8800c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case ARRAY16_OPF: 8810c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case ARRAY32_OPF: 8820c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller array(regs, insn, opf); 8830c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8840c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8850c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller /* Byte Mask and Shuffle Instructions */ 8860c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case BMASK_OPF: 8870c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller bmask(regs, insn); 8880c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8890c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8900c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller case BSHUFFLE_OPF: 8910c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller bshuffle(regs, insn); 8920c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller break; 8936cb79b3f3ba2b14590cac02ee13ab7410b6225edJoe Perches } 8940c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller 8950c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller regs->tpc = regs->tnpc; 8960c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller regs->tnpc += 4; 8970c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller return 0; 8980c51ed93ca0ecbf44ec096f4bd04c12a3e761e6bDavid S. Miller} 899