Add code to emulate unimplemented (non-fp) instructions and to fixup
unaligned accesses, and instr.h, which contrains definitions for the sparc64 instruction set (partly from NetBSD). Make use of some definitions from instr.h in db_disasm.c.
This commit is contained in:
parent
d3c9fa0463
commit
9b3b51bcab
@ -43,6 +43,11 @@ struct trapframe {
|
||||
uintptr_t tf_arg;
|
||||
};
|
||||
#define tf_sp tf_out[6]
|
||||
|
||||
#define TF_DONE(tf) do { \
|
||||
tf->tf_tpc = tf->tf_tnpc; \
|
||||
tf->tf_tnpc += 4; \
|
||||
} while (0)
|
||||
|
||||
struct mmuframe {
|
||||
u_long mf_sfar;
|
||||
|
620
sys/sparc64/include/instr.h
Normal file
620
sys/sparc64/include/instr.h
Normal file
@ -0,0 +1,620 @@
|
||||
/*
|
||||
* Copyright (c) 1994 David S. Miller, davem@nadzieja.rutgers.edu
|
||||
* Copyright (c) 1995 Paul Kranenburg
|
||||
* Copyright (c) 2001 Thomas Moestl <tmm@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by David Miller.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* from: NetBSD: db_disasm.c,v 1.9 2000/08/16 11:29:42 pk Exp
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_INSTR_H_
|
||||
#define _MACHINE_INSTR_H_
|
||||
|
||||
/*
|
||||
* Definitions for all instruction formats
|
||||
*/
|
||||
#define IF_OP_SHIFT 30
|
||||
#define IF_OP_BITS 2
|
||||
#define IF_IMM_SHIFT 0 /* Immediate/Displacement */
|
||||
|
||||
/*
|
||||
* Definitions for format 2
|
||||
*/
|
||||
#define IF_F2_RD_SHIFT 25
|
||||
#define IF_F2_RD_BITS 5
|
||||
#define IF_F2_A_SHIFT 29
|
||||
#define IF_F2_A_BITS 1
|
||||
#define IF_F2_COND_SHIFT 25
|
||||
#define IF_F2_COND_BITS 4
|
||||
#define IF_F2_RCOND_SHIFT 25
|
||||
#define IF_F2_RCOND_BITS 3
|
||||
#define IF_F2_OP2_SHIFT 22
|
||||
#define IF_F2_OP2_BITS 3
|
||||
#define IF_F2_CC1_SHIFT 21
|
||||
#define IF_F2_CC1_BITS 1
|
||||
#define IF_F2_CC0_SHIFT 20
|
||||
#define IF_F2_CC0_BITS 1
|
||||
#define IF_F2_D16HI_SHIFT 20
|
||||
#define IF_F2_D16HI_BITS 2
|
||||
#define IF_F2_P_SHIFT 19
|
||||
#define IF_F2_P_BITS 1
|
||||
#define IF_F2_RS1_SHIFT 14
|
||||
#define IF_F2_RS1_BITS 5
|
||||
|
||||
/*
|
||||
* Definitions for format 3
|
||||
*/
|
||||
#define IF_F3_OP3_SHIFT 19
|
||||
#define IF_F3_OP3_BITS 6
|
||||
#define IF_F3_RD_SHIFT IF_F2_RD_SHIFT
|
||||
#define IF_F3_RD_BITS IF_F2_RD_BITS
|
||||
#define IF_F3_FCN_SHIFT 25
|
||||
#define IF_F3_FCN_BITS 5
|
||||
#define IF_F3_CC1_SHIFT 26
|
||||
#define IF_F3_CC1_BITS 1
|
||||
#define IF_F3_CC0_SHIFT 25
|
||||
#define IF_F3_CC0_BITS 1
|
||||
#define IF_F3_RS1_SHIFT IF_F2_RS1_SHIFT
|
||||
#define IF_F3_RS1_BITS IF_F2_RS1_BITS
|
||||
#define IF_F3_I_SHIFT 13
|
||||
#define IF_F3_I_BITS 1
|
||||
#define IF_F3_X_SHIFT 12
|
||||
#define IF_F3_X_BITS 1
|
||||
#define IF_F3_RCOND_SHIFT 10
|
||||
#define IF_F3_RCOND_BITS 3
|
||||
#define IF_F3_IMM_ASI_SHIFT 5
|
||||
#define IF_F3_IMM_ASI_BITS 8
|
||||
#define IF_F3_OPF_SHIFT 5
|
||||
#define IF_F3_OPF_BITS 9
|
||||
#define IF_F3_CMASK_SHIFT 4
|
||||
#define IF_F3_CMASK_BITS 3
|
||||
#define IF_F3_RS2_SHIFT 0
|
||||
#define IF_F3_RS2_BITS 5
|
||||
#define IF_F3_SHCNT32_SHIFT 0
|
||||
#define IF_F3_SHCNT32_BITS 5
|
||||
#define IF_F3_SHCNT64_SHIFT 0
|
||||
#define IF_F3_SHCNT64_BITS 6
|
||||
|
||||
/*
|
||||
* Definitions for format 4
|
||||
*/
|
||||
#define IF_F4_OP3_SHIFT IF_F3_OP3_SHIFT
|
||||
#define IF_F4_OP3_BITS IF_F3_OP3_BITS
|
||||
#define IF_F4_RD_SHIFT IF_F2_RD_SHIFT
|
||||
#define IF_F4_RD_BITS IF_F2_RD_BITS
|
||||
#define IF_F4_RS1_SHIFT IF_F2_RS1_SHIFT
|
||||
#define IF_F4_RS1_BITS IF_F2_RS1_BITS
|
||||
#define IF_F4_TCOND_SHIFT IF_F2_COND_SHIFT /* cond for Tcc */
|
||||
#define IF_F4_TCOND_BITS IF_F2_COND_BITS
|
||||
#define IF_F4_CC2_SHIFT 18
|
||||
#define IF_F4_CC2_BITS 1
|
||||
#define IF_F4_COND_SHIFT 14
|
||||
#define IF_F4_COND_BITS 4
|
||||
#define IF_F4_I_SHIFT IF_F3_I_SHIFT
|
||||
#define IF_F4_I_BITS IF_F3_I_BITS
|
||||
#define IF_F4_OPF_CC_SHIFT 11
|
||||
#define IF_F4_OPF_CC_BITS 3
|
||||
#define IF_F4_CC1_SHIFT 12
|
||||
#define IF_F4_CC1_BITS 1
|
||||
#define IF_F4_CC0_SHIFT 11
|
||||
#define IF_F4_CC0_BITS 1
|
||||
#define IF_F4_RCOND_SHIFT IF_F3_RCOND_SHIFT
|
||||
#define IF_F4_RCOND_BITS IF_F3_RCOND_BITS
|
||||
#define IF_F4_OPF_LOW_SHIFT 5
|
||||
#define IF_F4_RS2_SHIFT IF_F3_RS2_SHIFT
|
||||
#define IF_F4_RS2_BITS IF_F3_RS2_BITS
|
||||
#define IF_F4_SW_TRAP_SHIFT 0
|
||||
#define IF_F4_SW_TRAP_BITS 7
|
||||
|
||||
/*
|
||||
* Macros to decode instructions
|
||||
*/
|
||||
/* Extract a field */
|
||||
#define IF_EXTRACT(x, s, w) (((x) >> (s)) & ((1 << (w)) - 1))
|
||||
#define IF_DECODE(x, f) \
|
||||
IF_EXTRACT((x), IF_ ## f ## _SHIFT, IF_ ## f ## _BITS)
|
||||
|
||||
/* Sign-extend a field of width W */
|
||||
#define IF_SEXT(x, w) \
|
||||
(((x) & (1 << ((w) - 1))) != 0 ? (-1L - ((x) ^ ((1 << (w)) - 1))) : (x))
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* The following C variant is from db_disassemble.c, and surely faster, but it
|
||||
* relies on behaviour that is undefined by the C standard (>> in conjunction
|
||||
* with signed negative arguments).
|
||||
*/
|
||||
#define IF_SEXT(v, w) ((((long long)(v)) << (64 - w)) >> (64 - w))
|
||||
/* Assembler version of the above */
|
||||
#define IF_SEXT(v, w) \
|
||||
{ u_long t; ( __asm __volatile("sllx %1, %2, %0; srax %0, %2, %0" :
|
||||
"=r" (t) : "r" (v) : "i" (64 - w)); t)}
|
||||
#endif
|
||||
|
||||
/* All instruction formats */
|
||||
#define IF_OP(i) IF_DECODE(i, OP)
|
||||
|
||||
/* Instruction format 2 */
|
||||
#define IF_F2_RD(i) IF_DECODE((i), F2_RD)
|
||||
#define IF_F2_A(i) IF_DECODE((i), F2_A)
|
||||
#define IF_F2_COND(i) IF_DECODE((i), F2_COND)
|
||||
#define IF_F2_RCOND(i) IF_DECODE((i), F2_RCOND)
|
||||
#define IF_F2_OP2(i) IF_DECODE((i), F2_OP2)
|
||||
#define IF_F2_CC1(i) IF_DECODE((i), F2_CC1)
|
||||
#define IF_F2_CC0(i) IF_DECODE((i), F2_CC0)
|
||||
#define IF_F2_D16HI(i) IF_DECODE((i), F2_D16HI)
|
||||
#define IF_F2_P(i) IF_DECODE((i), F2_P)
|
||||
#define IF_F2_RS1(i) IF_DECODE((i), F2_RS1)
|
||||
|
||||
/* Instruction format 3 */
|
||||
#define IF_F3_OP3(i) IF_DECODE((i), F3_OP3)
|
||||
#define IF_F3_RD(i) IF_F2_RD((i))
|
||||
#define IF_F3_FCN(i) IF_DECODE((i), F3_FCN)
|
||||
#define IF_F3_CC1(i) IF_DECODE((i), F3_CC1)
|
||||
#define IF_F3_CC0(i) IF_DECODE((i), F3_CC0)
|
||||
#define IF_F3_RS1(i) IF_F2_RS1((i))
|
||||
#define IF_F3_I(i) IF_DECODE((i), F3_I)
|
||||
#define IF_F3_X(i) IF_DECODE((i), F3_X)
|
||||
#define IF_F3_RCOND(i) IF_DECODE((i), F3_RCOND)
|
||||
#define IF_F3_IMM_ASI(i) IF_DECODE((i), F3_IMM_ASI)
|
||||
#define IF_F3_OPF(i) IF_DECODE((i), F3_OPF)
|
||||
#define IF_F3_CMASK(i) IF_DECODE((i), F3_CMASK)
|
||||
#define IF_F3_RS2(i) IF_DECODE((i), F3_RS2)
|
||||
#define IF_F3_SHCNT32(i) IF_DECODE((i), F3_SHCNT32)
|
||||
#define IF_F3_SHCNT64(i) IF_DECODE((i), F3_SHCNT64)
|
||||
|
||||
/* Instruction format 4 */
|
||||
#define IF_F4_OP3(i) IF_F3_OP3((i))
|
||||
#define IF_F4_RD(i) IF_F3_RD((i))
|
||||
#define IF_F4_TCOND(i) IF_DECODE((i), F4_TCOND)
|
||||
#define IF_F4_RS1(i) IF_F3_RS1((i))
|
||||
#define IF_F4_CC2(i) IF_DECODE((i), F4_CC2)
|
||||
#define IF_F4_COND(i) IF_DECODE((i), F4_COND)
|
||||
#define IF_F4_I(i) IF_F3_I((i))
|
||||
#define IF_F4_OPF_CC(i) IF_DECODE((i), F4_OPF_CC)
|
||||
#define IF_F4_RCOND(i) IF_F3_RCOND((i))
|
||||
#define IF_F4_OPF_LOW(i, w) IF_EXTRACT((i), IF_F4_OPF_LOW_SHIFT, (w))
|
||||
#define IF_F4_RS2(i) IF_F3_RS2((i))
|
||||
#define IF_F4_SW_TRAP(i) IF_DECODE((i), F4_SW_TRAP)
|
||||
|
||||
/* Extract an immediate from an instruction, with an without sign extension */
|
||||
#define IF_IMM(i, w) IF_EXTRACT((i), IF_IMM_SHIFT, (w))
|
||||
#define IF_SIMM(i, w) ({ u_long b = (w), x = IF_IMM((i), b); IF_SEXT((x), b); })
|
||||
|
||||
/*
|
||||
* Macros to encode instructions
|
||||
*/
|
||||
#define IF_INSERT(x, s, w) (((x) & ((1 << (w)) - 1)) << (s))
|
||||
#define IF_ENCODE(x, f) \
|
||||
IF_INSERT((x), IF_ ## f ## _SHIFT, IF_ ## f ## _BITS)
|
||||
|
||||
/* All instruction formats */
|
||||
#define EIF_OP(x) IF_ENCODE((x), OP)
|
||||
|
||||
/* Instruction format 2 */
|
||||
#define EIF_F2_RD(x) IF_ENCODE((x), F2_RD)
|
||||
#define EIF_F2_A(x) IF_ENCODE((x), F2_A)
|
||||
#define EIF_F2_COND(x) IF_ENCODE((x), F2_COND)
|
||||
#define EIF_F2_RCOND(x) IF_ENCODE((x), F2_RCOND)
|
||||
#define EIF_F2_OP2(x) IF_ENCODE((x), F2_OP2)
|
||||
#define EIF_F2_CC1(x) IF_ENCODE((x), F2_CC1)
|
||||
#define EIF_F2_CC0(x) IF_ENCODE((x), F2_CC0)
|
||||
#define EIF_F2_D16HI(x) IF_ENCODE((x), F2_D16HI)
|
||||
#define EIF_F2_P(x) IF_ENCODE((x), F2_P)
|
||||
#define EIF_F2_RS1(x) IF_ENCODE((x), F2_RS1)
|
||||
|
||||
/* Instruction format 3 */
|
||||
#define EIF_F3_OP3(x) IF_ENCODE((x), F3_OP3)
|
||||
#define EIF_F3_RD(x) EIF_F2_RD((x))
|
||||
#define EIF_F3_FCN(x) IF_ENCODE((x), F3_FCN)
|
||||
#define EIF_F3_CC1(x) IF_ENCODE((x), F3_CC1)
|
||||
#define EIF_F3_CC0(x) IF_ENCODE((x), F3_CC0)
|
||||
#define EIF_F3_RS1(x) EIF_F2_RS1((x))
|
||||
#define EIF_F3_I(x) IF_ENCODE((x), F3_I)
|
||||
#define EIF_F3_X(x) IF_ENCODE((x), F3_X)
|
||||
#define EIF_F3_RCOND(x) IF_ENCODE((x), F3_RCOND)
|
||||
#define EIF_F3_IMM_ASI(x) IF_ENCODE((x), F3_IMM_ASI)
|
||||
#define EIF_F3_OPF(x) IF_ENCODE((x), F3_OPF)
|
||||
#define EIF_F3_CMASK(x) IF_ENCODE((x), F3_CMASK)
|
||||
#define EIF_F3_RS2(x) IF_ENCODE((x), F3_RS2)
|
||||
#define EIF_F3_SHCNT32(x) IF_ENCODE((x), F3_SHCNT32)
|
||||
#define EIF_F3_SHCNT64(x) IF_ENCODE((x), F3_SHCNT64)
|
||||
|
||||
/* Instruction format 4 */
|
||||
#define EIF_F4_OP3(x) EIF_F3_OP3((x))
|
||||
#define EIF_F4_RD(x) EIF_F2_RD((x))
|
||||
#define EIF_F4_TCOND(x) IF_ENCODE((x), F4_TCOND)
|
||||
#define EIF_F4_RS1(x) EIF_F2_RS1((x))
|
||||
#define EIF_F4_CC2(x) IF_ENCODE((x), F4_CC2)
|
||||
#define EIF_F4_COND(x) IF_ENCODE((x), F4_COND)
|
||||
#define EIF_F4_I(x) EIF_F3_I((x))
|
||||
#define EIF_F4_OPF_CC(x) IF_ENCODE((x), F4_OPF_CC)
|
||||
#define EIF_F4_RCOND(x) EIF_F3_RCOND((x))
|
||||
#define EIF_F4_OPF_LOW(i, w) IF_INSERT((x), IF_F4_OPF_CC_SHIFT, (w))
|
||||
#define EIF_F4_RS2(x) EIF_F3_RS2((x))
|
||||
#define EIF_F4_SW_TRAP(x) IF_ENCODE((x), F4_SW_TRAP)
|
||||
|
||||
/* Immediates */
|
||||
#define EIF_IMM(x, w) IF_INSERT((x), IF_IMM_SHIFT, (w))
|
||||
#define EIF_SIMM(x, w) IF_EIMM((x), (w))
|
||||
|
||||
/*
|
||||
* OP field values (specifying the instruction format)
|
||||
*/
|
||||
#define IOP_FORM2 0x00 /* Format 2: sethi, branches */
|
||||
#define IOP_CALL 0x01 /* Format 1: call */
|
||||
#define IOP_MISC 0x02 /* Format 3 or 4: arith & misc */
|
||||
#define IOP_LDST 0x03 /* Format 4: loads and stores */
|
||||
|
||||
/*
|
||||
* OP2/OP3 values (specifying the actual instruction)
|
||||
*/
|
||||
/* OP2 values for format 2 (OP = 0) */
|
||||
#define INS0_ILLTRAP 0x00
|
||||
#define INS0_BPcc 0x01
|
||||
#define INS0_Bicc 0x02
|
||||
#define INS0_BPr 0x03
|
||||
#define INS0_SETHI 0x04 /* with rd = 0 and imm22 = 0, nop */
|
||||
#define INS0_FBPfcc 0x05
|
||||
#define INS0_FBfcc 0x06
|
||||
/* undefined 0x07 */
|
||||
|
||||
/* OP3 values for Format 3 and 4 (OP = 2) */
|
||||
#define INS2_ADD 0x00
|
||||
#define INS2_AND 0x01
|
||||
#define INS2_OR 0x02
|
||||
#define INS2_XOR 0x03
|
||||
#define INS2_SUB 0x04
|
||||
#define INS2_ANDN 0x05
|
||||
#define INS2_ORN 0x06
|
||||
#define INS2_XNOR 0x07
|
||||
#define INS2_ADDC 0x08
|
||||
#define INS2_MULX 0x09
|
||||
#define INS2_UMUL 0x0a
|
||||
#define INS2_SMUL 0x0b
|
||||
#define INS2_SUBC 0x0c
|
||||
#define INS2_UDIVX 0x0d
|
||||
#define INS2_UDIV 0x0e
|
||||
#define INS2_SDIV 0x0f
|
||||
#define INS2_ADDcc 0x10
|
||||
#define INS2_ANDcc 0x11
|
||||
#define INS2_ORcc 0x12
|
||||
#define INS2_XORcc 0x13
|
||||
#define INS2_SUBcc 0x14
|
||||
#define INS2_ANDNcc 0x15
|
||||
#define INS2_ORNcc 0x16
|
||||
#define INS2_XNORcc 0x17
|
||||
#define INS2_ADDCcc 0x18
|
||||
/* undefined 0x19 */
|
||||
#define INS2_UMULcc 0x1a
|
||||
#define INS2_SMULcc 0x1b
|
||||
#define INS2_SUBCcc 0x1c
|
||||
/* undefined 0x1d */
|
||||
#define INS2_UDIVcc 0x1e
|
||||
#define INS2_SDIVcc 0x1f
|
||||
#define INS2_TADDcc 0x20
|
||||
#define INS2_TSUBcc 0x21
|
||||
#define INS2_TADDccTV 0x22
|
||||
#define INS2_TSUBccTV 0x23
|
||||
#define INS2_MULScc 0x24
|
||||
#define INS2_SSL 0x25 /* SLLX when IF_X(i) == 1 */
|
||||
#define INS2_SRL 0x26 /* SRLX when IF_X(i) == 1 */
|
||||
#define INS2_SRA 0x27 /* SRAX when IF_X(i) == 1 */
|
||||
#define INS2_RD 0x28 /* and MEMBAR, STBAR */
|
||||
/* undefined 0x29 */
|
||||
#define INS2_RDPR 0x2a
|
||||
#define INS2_FLUSHW 0x2b
|
||||
#define INS2_MOVcc 0x2c
|
||||
#define INS2_SDIVX 0x2d
|
||||
#define INS2_POPC 0x2e /* undefined if IF_RS1(i) != 0 */
|
||||
#define INS2_MOVr 0x2f
|
||||
#define INS2_WR 0x30 /* and SIR */
|
||||
#define INS2_SV_RSTR 0x31 /* saved, restored */
|
||||
#define INS2_WRPR 0x32
|
||||
/* undefined 0x33 */
|
||||
#define INS2_FPop1 0x34 /* further encoded in opf field */
|
||||
#define INS2_FPop2 0x35 /* further encoded in opf field */
|
||||
#define INS2_IMPLDEP1 0x36
|
||||
#define INS2_IMPLDEP2 0x37
|
||||
#define INS2_JMPL 0x38
|
||||
#define INS2_RETURN 0x39
|
||||
#define INS2_Tcc 0x3a
|
||||
#define INS2_FLUSH 0x3b
|
||||
#define INS2_SAVE 0x3c
|
||||
#define INS2_RESTORE 0x3d
|
||||
#define INS2_DONE_RETR 0x3e /* done, retry */
|
||||
/* undefined 0x3f */
|
||||
|
||||
/* OP3 values for format 3 (OP = 3) */
|
||||
#define INS3_LDUW 0x00
|
||||
#define INS3_LDUB 0x01
|
||||
#define INS3_LDUH 0x02
|
||||
#define INS3_LDD 0x03
|
||||
#define INS3_STW 0x04
|
||||
#define INS3_STB 0x05
|
||||
#define INS3_STH 0x06
|
||||
#define INS3_STD 0x07
|
||||
#define INS3_LDSW 0x08
|
||||
#define INS3_LDSB 0x09
|
||||
#define INS3_LDSH 0x0a
|
||||
#define INS3_LDX 0x0b
|
||||
/* undefined 0x0c */
|
||||
#define INS3_LDSTUB 0x0d
|
||||
#define INS3_STX 0x0e
|
||||
#define INS3_SWAP 0x0f
|
||||
#define INS3_LDUWA 0x10
|
||||
#define INS3_LDUBA 0x11
|
||||
#define INS3_LDUHA 0x12
|
||||
#define INS3_LDDA 0x13
|
||||
#define INS3_STWA 0x14
|
||||
#define INS3_STBA 0x15
|
||||
#define INS3_STHA 0x16
|
||||
#define INS3_STDA 0x17
|
||||
#define INS3_LDSWA 0x18
|
||||
#define INS3_LDSBA 0x19
|
||||
#define INS3_LDSHA 0x1a
|
||||
#define INS3_LDXA 0x1b
|
||||
/* undefined 0x1c */
|
||||
#define INS3_LDSTUBA 0x1d
|
||||
#define INS3_STXA 0x1e
|
||||
#define INS3_SWAPA 0x1f
|
||||
#define INS3_LDF 0x20
|
||||
#define INS3_LDFSR 0x21 /* and LDXFSR */
|
||||
#define INS3_LDQF 0x22
|
||||
#define INS3_LDDF 0x23
|
||||
#define INS3_STF 0x24
|
||||
#define INS3_STFSR 0x25 /* and STXFSR */
|
||||
#define INS3_STQF 0x26
|
||||
#define INS3_STDF 0x27
|
||||
/* undefined 0x28 - 0x2c */
|
||||
#define INS3_PREFETCH 0x2d
|
||||
/* undefined 0x2e - 0x2f */
|
||||
#define INS3_LDFA 0x30
|
||||
/* undefined 0x31 */
|
||||
#define INS3_LDQFA 0x32
|
||||
#define INS3_LDDFA 0x33
|
||||
#define INS3_STFA 0x34
|
||||
/* undefined 0x35 */
|
||||
#define INS3_STQFA 0x36
|
||||
#define INS3_STDFA 0x37
|
||||
/* undefined 0x38 - 0x3b */
|
||||
#define INS3_CASA 0x39
|
||||
#define INS3_PREFETCHA 0x3a
|
||||
#define INS3_CASXA 0x3b
|
||||
|
||||
/*
|
||||
* OPF values (floating point instructions, IMPLDEP)
|
||||
*/
|
||||
/* FPop1 */
|
||||
#define INSFP1_FMOVs 0x001
|
||||
#define INSFP1_FMOVd 0x002
|
||||
#define INSFP1_FMOVq 0x003
|
||||
#define INSFP1_FNEGs 0x005
|
||||
#define INSFP1_FNEGd 0x006
|
||||
#define INSFP1_FNEGq 0x007
|
||||
#define INSFP1_FABSs 0x009
|
||||
#define INSFP1_FABSd 0x00a
|
||||
#define INSFP1_FABSq 0x00b
|
||||
#define INSFP1_FSQRTs 0x029
|
||||
#define INSFP1_FSQRTd 0x02a
|
||||
#define INSFP1_FSQRTq 0x02b
|
||||
#define INSFP1_FADDs 0x041
|
||||
#define INSFP1_FADDd 0x042
|
||||
#define INSFP1_FADDq 0x043
|
||||
#define INSFP1_FSUBs 0x045
|
||||
#define INSFP1_FSUBd 0x046
|
||||
#define INSFP1_FSUBq 0x047
|
||||
#define INSFP1_FMULs 0x049
|
||||
#define INSFP1_FMULd 0x04a
|
||||
#define INSFP1_FMULq 0x04b
|
||||
#define INSFP1_FDIVs 0x04d
|
||||
#define INSFP1_FDIVd 0x04e
|
||||
#define INSFP1_FDIVq 0x04f
|
||||
#define INSFP1_FsMULd 0x069
|
||||
#define INSFP1_FdMULq 0x06e
|
||||
#define INSFP1_FsTOx 0x081
|
||||
#define INSFP1_FdTOx 0x082
|
||||
#define INSFP1_FqTOx 0x083
|
||||
#define INSFP1_FxTOs 0x084
|
||||
#define INSFP1_FxTOd 0x088
|
||||
#define INSFP1_FxTOq 0x08c
|
||||
#define INSFP1_FiTOs 0x0c4
|
||||
#define INSFP1_FdTOs 0x0c6
|
||||
#define INSFP1_FqTOs 0x0c7
|
||||
#define INSFP1_FiTOd 0x0c8
|
||||
#define INSFP1_FsTOd 0x0c9
|
||||
#define INSFP1_FqTOd 0x0cb
|
||||
#define INSFP1_FiTOq 0x0cc
|
||||
#define INSFP1_FsTOq 0x0cd
|
||||
#define INSFP1_FdTOq 0x0ce
|
||||
|
||||
/* FPop2 */
|
||||
#define INSFP2_FMOV_CCMUL 0x40
|
||||
/* use the IFCC_* constants for cc */
|
||||
#define INSFP2_FMOV_CC(i, cc) (i + (cc) * INSFP2_FMOV_CCMUL)
|
||||
#define INSFP2_FMOVs(cc) INSFP2_FMOV_CC(0x01, (cc))
|
||||
#define INSFP2_FMOVd(cc) INSFP2_FMOV_CC(0x02, (cc))
|
||||
#define INSFP2_FMOVq(cc) INSFP2_FMOV_CC(0x03, (cc))
|
||||
|
||||
/* use the IRCOND_* constants for rc */
|
||||
#define INSFP2_FMOV_RCMUL 0x20
|
||||
#define INSFP2_FMOV_RC(i, rc) (i + (rc) * INSFP2_FMOV_RCMUL)
|
||||
#define INSFP2_FMOVRsZ(rc) INSFP2_FMOV_RC(0x05, (rc))
|
||||
#define INSFP2_FMOVRdZ(rc) INSFP2_FMOV_RC(0x06, (rc))
|
||||
#define INSFP2_FMOVRqZ(rc) INSFP2_FMOV_RC(0x07, (rc))
|
||||
#define INSFP2_FCMPs 0x051
|
||||
#define INSFP2_FCMPd 0x052
|
||||
#define INSFP2_FCMPq 0x053
|
||||
#define INSFP2_FCMPEs 0x055
|
||||
#define INSFP2_FCMPEd 0x056
|
||||
#define INSFP2_FCMPEq 0x057
|
||||
|
||||
/* IMPLDEP1 for Sun UltraSparc */
|
||||
#define IIDP1_EDGE8 0x00
|
||||
#define IIDP1_EDGE8L 0x02
|
||||
#define IIDP1_EDGE16 0x04
|
||||
#define IIDP1_EDGE16L 0x06
|
||||
#define IIDP1_EDGE32 0x08
|
||||
#define IIDP1_EDGE32L 0x0a
|
||||
#define IIDP1_ARRAY8 0x10
|
||||
#define IIDP1_ARRAY16 0x12
|
||||
#define IIDP1_ARRAY32 0x14
|
||||
#define IIDP1_ALIGNADDRESS 0x18
|
||||
#define IIDP1_ALIGNADDRESS_L 0x1a
|
||||
#define IIDP1_FCMPLE16 0x20
|
||||
#define IIDP1_FCMPNE16 0x22
|
||||
#define IIDP1_FCMPLE32 0x24
|
||||
#define IIDP1_FCMPNE32 0x26
|
||||
#define IIDP1_FCMPGT16 0x28
|
||||
#define IIDP1_FCMPEQ16 0x2a
|
||||
#define IIDP1_FCMPGT32 0x2c
|
||||
#define IIDP1_FCMPEQ32 0x2e
|
||||
#define IIDP1_FMUL8x16 0x31
|
||||
#define IIDP1_FMUL8x16AU 0x33
|
||||
#define IIDP1_FMUL8X16AL 0x35
|
||||
#define IIDP1_FMUL8SUx16 0x36
|
||||
#define IIDP1_FMUL8ULx16 0x37
|
||||
#define IIDP1_FMULD8SUx16 0x38
|
||||
#define IIDP1_FMULD8ULx16 0x39
|
||||
#define IIDP1_FPACK32 0x3a
|
||||
#define IIDP1_FPACK16 0x3b
|
||||
#define IIDP1_FPACKFIX 0x3d
|
||||
#define IIDP1_PDIST 0x3e
|
||||
#define IIDP1_FALIGNDATA 0x48
|
||||
#define IIDP1_FPMERGE 0x4b
|
||||
#define IIDP1_FEXPAND 0x4d
|
||||
#define IIDP1_FPADD16 0x50
|
||||
#define IIDP1_FPADD16S 0x51
|
||||
#define IIDP1_FPADD32 0x52
|
||||
#define IIDP1_FPADD32S 0x53
|
||||
#define IIDP1_SUB16 0x54
|
||||
#define IIDP1_SUB16S 0x55
|
||||
#define IIDP1_SUB32 0x56
|
||||
#define IIDP1_SUB32S 0x57
|
||||
#define IIDP1_FZERO 0x60
|
||||
#define IIDP1_FZEROS 0x61
|
||||
#define IIDP1_FNOR 0x62
|
||||
#define IIDP1_FNORS 0x63
|
||||
#define IIDP1_FANDNOT2 0x64
|
||||
#define IIDP1_FANDNOT2S 0x65
|
||||
#define IIDP1_NOT2 0x66
|
||||
#define IIDP1_NOT2S 0x67
|
||||
#define IIDP1_FANDNOT1 0x68
|
||||
#define IIDP1_FANDNOT1S 0x69
|
||||
#define IIDP1_FNOT1 0x6a
|
||||
#define IIDP1_FNOT1S 0x6b
|
||||
#define IIDP1_FXOR 0x6c
|
||||
#define IIDP1_FXORS 0x6d
|
||||
#define IIDP1_FNAND 0x6e
|
||||
#define IIDP1_FNANDS 0x6f
|
||||
#define IIDP1_FAND 0x70
|
||||
#define IIDP1_FANDS 0x71
|
||||
#define IIDP1_FXNOR 0x72
|
||||
#define IIDP1_FXNORS 0x73
|
||||
#define IIDP1_FSRC1 0x74
|
||||
#define IIDP1_FSRC1S 0x75
|
||||
#define IIDP1_FORNOT2 0x76
|
||||
#define IIDP1_FORNOT2S 0x77
|
||||
#define IIDP1_FSRC2 0x78
|
||||
#define IIDP1_FSRC2S 0x79
|
||||
#define IIDP1_FORNOT1 0x7a
|
||||
#define IIDP1_FORNOT1S 0x7b
|
||||
#define IIDP1_FOR 0x7c
|
||||
#define IIDP1_FORS 0x7d
|
||||
#define IIDP1_FONE 0x7e
|
||||
#define IIDP1_FONES 0x7f
|
||||
#define IIDP1_SHUTDOWN 0x80
|
||||
|
||||
/*
|
||||
* Instruction modifiers
|
||||
*/
|
||||
/* cond values for integer ccr's */
|
||||
#define IICOND_N 0x00
|
||||
#define IICOND_E 0x01
|
||||
#define IICOND_LE 0x02
|
||||
#define IICOND_L 0x03
|
||||
#define IICOND_LEU 0x04
|
||||
#define IICOND_CS 0x05
|
||||
#define IICOND_NEG 0x06
|
||||
#define IICOND_VS 0x07
|
||||
#define IICOND_A 0x08
|
||||
#define IICOND_NE 0x09
|
||||
#define IICOND_G 0x0a
|
||||
#define IICOND_GE 0x0b
|
||||
#define IICOND_GU 0x0c
|
||||
#define IICOND_CC 0x0d
|
||||
#define IICOND_POS 0x0e
|
||||
#define IICOND_VC 0x0f
|
||||
|
||||
/* cond values for fp ccr's */
|
||||
#define IFCOND_N 0x00
|
||||
#define IFCOND_NE 0x01
|
||||
#define IFCOND_LG 0x02
|
||||
#define IFCOND_UL 0x03
|
||||
#define IFCOND_L 0x04
|
||||
#define IFCOND_UG 0x05
|
||||
#define IFCOND_G 0x06
|
||||
#define IFCOND_U 0x07
|
||||
#define IFCOND_A 0x08
|
||||
#define IFCOND_E 0x09
|
||||
#define IFCOND_UE 0x0a
|
||||
#define IFCOND_GE 0x0b
|
||||
#define IFCOND_UGE 0x0c
|
||||
#define IFCOND_LE 0x0d
|
||||
#define IFCOND_ULE 0x0e
|
||||
#define IFCOND_O 0x0f
|
||||
|
||||
/* rcond values for BPr, MOVr, FMOVr */
|
||||
#define IRCOND_RZ 0x01
|
||||
#define IRCOND_LEZ 0x02
|
||||
#define IRCOND_LZ 0x03
|
||||
#define IRCOND_NZ 0x05
|
||||
#define IRCOND_GZ 0x06
|
||||
#define IRCOND_GEZ 0x07
|
||||
|
||||
/* cc values for MOVcc and FMOVcc */
|
||||
#define IFCC_ICC 0x04
|
||||
#define IFCC_XCC 0x06
|
||||
/* if true, the lower 2 bits are the fcc number */
|
||||
#define IFCC_FCC(c) (((c) & 4) == 0)
|
||||
|
||||
/* cc values for BPc and Tcc */
|
||||
#define IBCC_ICC 0x00
|
||||
#define IBCC_XCC 0x02
|
||||
|
||||
/*
|
||||
* Integer registers
|
||||
*/
|
||||
#define IREG_G0 0x00
|
||||
#define IREG_O0 0x08
|
||||
#define IREG_L0 0x10
|
||||
#define IREQ_I0 0x18
|
||||
|
||||
#endif /* !_MACHINE_INSTR_H_ */
|
@ -38,17 +38,8 @@
|
||||
#include <ddb/db_sym.h>
|
||||
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/instr.h>
|
||||
|
||||
#ifndef V9
|
||||
#define V9
|
||||
#endif
|
||||
|
||||
/* Sign extend values */
|
||||
#ifdef V9
|
||||
#define SIGNEX(v,width) ((((long long)(v))<<(64-width))>>(64-width))
|
||||
#else
|
||||
#define SIGNEX(v,width) ((((int)(v))<<(32-width))>>(32-width))
|
||||
#endif
|
||||
#define SIGN(v) (((v)<0)?"-":"")
|
||||
|
||||
/*
|
||||
@ -68,40 +59,12 @@
|
||||
* 0000 0000 0000 0000 0001 0000 0000 0000 X bit, format 3 only
|
||||
*/
|
||||
|
||||
#define OP(x) (((x) & 0x3) << 30)
|
||||
#define OP2(x) (((x) & 0x7) << 22)
|
||||
#define OP3(x) (((x) & 0x3f) << 19)
|
||||
#define OPF(x) (((x) & 0x1ff) << 5)
|
||||
#define F3I(x) (((x) & 0x1) << 13)
|
||||
|
||||
/* various other fields */
|
||||
|
||||
#define A(x) (((x) & 0x1) << 29)
|
||||
#define P(x) (((x) & 0x1) << 19)
|
||||
#define X(x) (((x) & 0x1) << 12)
|
||||
#define FCN(x) (((x) & 0x1f) << 25)
|
||||
#define RCOND2(x) (((x) & 0x7) << 25)
|
||||
#define RCOND34(x) (((x) & 0x7) << 10)
|
||||
#define COND(x) (((x) & 0xf) << 25)
|
||||
#define SW_TRAP(x) ((x) & 0x7f)
|
||||
#define SHCNT32(x) ((x) & 0x1f)
|
||||
#define SHCNT64(x) ((x) & 0x3f)
|
||||
#define IMM11(x) ((x) & 0x7ff)
|
||||
#define IMM22(x) ((x) & 0x3fffff)
|
||||
#define DISP19(x) ((x) & 0x7ffff)
|
||||
#define DISP22(x) ((x) & 0x3fffff)
|
||||
#define DISP30(x) ((x) & 0x3fffffffL)
|
||||
|
||||
/* Register Operand Fields */
|
||||
#define RS1(x) (((x) & 0x1f) << 14)
|
||||
#define RS2(x) ((x) & 0x1f)
|
||||
#define RD(x) (((x) & 0x1f) << 25)
|
||||
|
||||
/* FORMAT macros used in sparc_i table to decode each opcode */
|
||||
#define FORMAT1(a) (OP(a))
|
||||
#define FORMAT2(a,b) (OP(a) | OP2(b))
|
||||
#define FORMAT3(a,b,c) (OP(a) | OP3(b) | F3I(c))
|
||||
#define FORMAT3F(a,b,c) (OP(a) | OP3(b) | OPF(c))
|
||||
#define FORMAT1(a) (EIF_OP(a))
|
||||
#define FORMAT2(a,b) (EIF_OP(a) | EIF_F2_OP2(b))
|
||||
/* For formats 3 and 4 */
|
||||
#define FORMAT3(a,b,c) (EIF_OP(a) | EIF_F3_OP3(b) | EIF_F3_I(c))
|
||||
#define FORMAT3F(a,b,c) (EIF_OP(a) | EIF_F3_OP3(b) | EIF_F3_OPF(c))
|
||||
|
||||
/* Helper macros to construct OP3 & OPF */
|
||||
#define OP3_X(x,y) ((((x) & 3) << 4) | ((y) & 0xf))
|
||||
@ -215,84 +178,85 @@ struct sparc_insn sparc_i[] = {
|
||||
{(FORMAT2(0, 0x4)), "sethi", "Cd"},
|
||||
|
||||
/* Branch on Integer Co`ndition Codes "Bicc" */
|
||||
{(FORMAT2(0, 2) | COND(8)), "ba", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(0)), "bn", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(9)), "bne", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(1)), "be", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(10)), "bg", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(2)), "ble", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(11)), "bge", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(3)), "bl", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(12)), "bgu", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(4)), "bleu", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(13)), "bcc", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(5)), "bcs", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(14)), "bpos", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(6)), "bneg", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(15)), "bvc", "a,m"},
|
||||
{(FORMAT2(0, 2) | COND(7)), "bvs", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(8)), "ba", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(0)), "bn", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(9)), "bne", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(1)), "be", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(10)), "bg", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(2)), "ble", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(11)), "bge", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(3)), "bl", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(12)), "bgu", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(4)), "bleu", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(13)), "bcc", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(5)), "bcs", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(14)), "bpos", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(6)), "bneg", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(15)), "bvc", "a,m"},
|
||||
{(FORMAT2(0, 2) | EIF_F2_COND(7)), "bvs", "a,m"},
|
||||
|
||||
/* Branch on Integer Condition Codes with Prediction "BPcc" */
|
||||
{(FORMAT2(0, 1) | COND(8)), "ba", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(0)), "bn", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(9)), "bne", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(1)), "be", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(10)), "bg", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(2)), "ble", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(11)), "bge", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(3)), "bl", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(12)), "bgu", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(4)), "bleu", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(13)), "bcc", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(5)), "bcs", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(14)), "bpos", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(6)), "bneg", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(15)), "bvc", "ap,u"},
|
||||
{(FORMAT2(0, 1) | COND(7)), "bvs", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(8)), "ba", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(0)), "bn", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(9)), "bne", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(1)), "be", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(10)), "bg", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(2)), "ble", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(11)), "bge", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(3)), "bl", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(12)), "bgu", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(4)), "bleu", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(13)), "bcc", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(5)), "bcs", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(14)), "bpos", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(6)), "bneg", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(15)), "bvc", "ap,u"},
|
||||
{(FORMAT2(0, 1) | EIF_F2_COND(7)), "bvs", "ap,u"},
|
||||
|
||||
/* Branch on Integer Register with Prediction "BPr" */
|
||||
{(FORMAT2(0, 3) | RCOND2(1)), "brz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | A(1) | P(1) | RCOND2(2)), "brlex", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(3)), "brlz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(5)), "brnz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(6)), "brgz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | RCOND2(7)), "brgez", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | EIF_F2_RCOND(1)), "brz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | EIF_F2_A(1) | EIF_F2_P(1) |
|
||||
EIF_F2_RCOND(2)), "brlex", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | EIF_F2_RCOND(3)), "brlz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | EIF_F2_RCOND(5)), "brnz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | EIF_F2_RCOND(6)), "brgz", "ap,1l"},
|
||||
{(FORMAT2(0, 3) | EIF_F2_RCOND(7)), "brgez", "ap,1l"},
|
||||
|
||||
/* Branch on Floating-Point Condition Codes with Prediction "FBPfcc" */
|
||||
{(FORMAT2(0, 5) | COND(8)), "fba", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(0)), "fbn", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(7)), "fbu", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(6)), "fbg", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(5)), "fbug", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(4)), "fbl", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(3)), "fbul", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(2)), "fblg", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(1)), "fbne", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(9)), "fbe", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(10)), "fbue", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(11)), "fbge", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(12)), "fbuge", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(13)), "fble", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(14)), "fbule", "ap,m"},
|
||||
{(FORMAT2(0, 5) | COND(15)), "fbo", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(8)), "fba", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(0)), "fbn", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(7)), "fbu", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(6)), "fbg", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(5)), "fbug", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(4)), "fbl", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(3)), "fbul", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(2)), "fblg", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(1)), "fbne", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(9)), "fbe", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(10)), "fbue", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(11)), "fbge", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(12)), "fbuge", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(13)), "fble", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(14)), "fbule", "ap,m"},
|
||||
{(FORMAT2(0, 5) | EIF_F2_COND(15)), "fbo", "ap,m"},
|
||||
|
||||
/* Branch on Floating-Point Condition Codes "FBfcc" */
|
||||
{(FORMAT2(0, 6) | COND(8)), "fba", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(0)), "fbn", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(7)), "fbu", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(6)), "fbg", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(5)), "fbug", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(4)), "fbl", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(3)), "fbul", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(2)), "fblg", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(1)), "fbne", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(9)), "fbe", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(10)), "fbue", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(11)), "fbge", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(12)), "fbuge", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(13)), "fble", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(14)), "fbule", "a,m"},
|
||||
{(FORMAT2(0, 6) | COND(15)), "fbo", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(8)), "fba", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(0)), "fbn", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(7)), "fbu", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(6)), "fbg", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(5)), "fbug", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(4)), "fbl", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(3)), "fbul", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(2)), "fblg", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(1)), "fbne", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(9)), "fbe", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(10)), "fbue", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(11)), "fbge", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(12)), "fbuge", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(13)), "fble", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(14)), "fbule", "a,m"},
|
||||
{(FORMAT2(0, 6) | EIF_F2_COND(15)), "fbo", "a,m"},
|
||||
|
||||
|
||||
|
||||
@ -305,14 +269,9 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(1,0), 1), "addcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,0), 0), "taddcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,0), 1), "taddcc", "1id"},
|
||||
#ifdef V9
|
||||
{(FORMAT3(2, 0x30, 1) | RD(0xf)), "sir", "i"},
|
||||
{(FORMAT3(2, 0x30, 1) | EIF_F3_RD(0xf)), "sir", "i"},
|
||||
{FORMAT3(2, OP3_X(3,0), 0), "wr", "12H"},
|
||||
{FORMAT3(2, OP3_X(3,0), 1), "wr", "1iH"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,0), 0), "wr", "12Y"}, /* wr 1, 2, %y */
|
||||
{FORMAT3(2, OP3_X(3,0), 1), "wr", "1iY"}, /* wr 1, i, %y */
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(0,1), 0), "and", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,1), 1), "and", "1id"},
|
||||
@ -320,13 +279,8 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(1,1), 1), "andcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,1), 0), "tsubcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,1), 1), "tsubcc", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(3,1), 0), "saved", ""},
|
||||
{FORMAT3(2, OP3_X(3,1), 0)|FCN(1), "restored", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,1), 0), "wr", "12P"}, /* wr 1, 2, %psr */
|
||||
{FORMAT3(2, OP3_X(3,1), 1), "wr", "1iP"}, /* wr 1, i, %psr */
|
||||
#endif
|
||||
{FORMAT3(2, OP3_X(3,1), 0) | EIF_F3_FCN(1), "restored", ""},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,2), 0), "or", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,2), 1), "or", "1id"},
|
||||
@ -334,13 +288,8 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(1,2), 1), "orcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,2), 0), "taddcctv", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,2), 1), "taddcctv", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(3,2), 0), "wrpr", "12G"},
|
||||
{FORMAT3(2, OP3_X(3,2), 1), "wrpr", "1iG"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,2), 0), "wr", "12W"}, /* wr 1, 2, %wim */
|
||||
{FORMAT3(2, OP3_X(3,2), 1), "wr", "1iW"}, /* wr 1, i, %wim */
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(0,3), 0), "xor", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,3), 1), "xor", "1id"},
|
||||
@ -348,12 +297,7 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(1,3), 1), "xorcc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,3), 0), "tsubcctv", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,3), 1), "tsubcctv", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(3,3), 0), "UNDEFINED", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(3,3), 0), "wr", "12T"}, /* wr 1, 2, %tbr */
|
||||
{FORMAT3(2, OP3_X(3,3), 1), "wr", "1iT"}, /* wr 1, i, %tbr */
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(0,4), 0), "sub", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,4), 1), "sub", "1id"},
|
||||
@ -369,8 +313,8 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(1,5), 1), "andncc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,5), 0), "sll", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,5), 1), "sll", "1Dd"},
|
||||
{FORMAT3(2, OP3_X(2,5), 0)|X(1), "sllx", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,5), 1)|X(1), "sllx", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(2,5), 0) | EIF_F3_X(1), "sllx", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,5), 1) | EIF_F3_X(1), "sllx", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(3,5), 1), "FPop2", ""}, /* see below */
|
||||
|
||||
{FORMAT3(2, OP3_X(0,6), 0), "orn", "12d"},
|
||||
@ -379,8 +323,8 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(1,6), 1), "orncc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,6), 0), "srl", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,6), 1), "srl", "1Dd"},
|
||||
{FORMAT3(2, OP3_X(2,6), 0)|X(1), "srlx", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,6), 1)|X(1), "srlx", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(2,6), 0) | EIF_F3_X(1), "srlx", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,6), 1) | EIF_F3_X(1), "srlx", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(3,6), 1), "impdep1", ""},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,7), 0), "xorn", "12d"},
|
||||
@ -389,21 +333,17 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(1,7), 1), "xorncc", "1id"},
|
||||
{FORMAT3(2, OP3_X(2,7), 0), "sra", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,7), 1), "sra", "1Dd"},
|
||||
{FORMAT3(2, OP3_X(2,7), 0)|X(1), "srax", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,7), 1)|X(1), "srax", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(2,7), 0) | EIF_F3_X(1), "srax", "12d"},
|
||||
{FORMAT3(2, OP3_X(2,7), 1) | EIF_F3_X(1), "srax", "1Ed"},
|
||||
{FORMAT3(2, OP3_X(3,7), 1), "impdep2", ""},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,8), 0), "addc", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,8), 1), "addc", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,8), 0), "addccc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,8), 1), "addccc", "1id"},
|
||||
#ifdef V9
|
||||
{(FORMAT3(2, 0x28, 1) | RS1(15)), "membar", "9"},
|
||||
{(FORMAT3(2, 0x28, 0) | RS1(15)), "stbar", ""},
|
||||
{(FORMAT3(2, 0x28, 1) | EIF_F3_RS1(15)), "membar", "9"},
|
||||
{(FORMAT3(2, 0x28, 0) | EIF_F3_RS1(15)), "stbar", ""},
|
||||
{FORMAT3(2, OP3_X(2,8), 0), "rd", "Bd"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,8), 0), "rd", "Yd"},
|
||||
#endif
|
||||
|
||||
{FORMAT3(2, OP3_X(3,8), 0), "jmpl", "pd"},
|
||||
{FORMAT3(2, OP3_X(3,8), 1), "jmpl", "qd"},
|
||||
@ -411,11 +351,7 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(0,9), 0), "mulx", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,9), 1), "mulx", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,9), 0), "UNDEFINED", ""},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(2,9), 0), "UNDEFINED", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,9), 0), "rd", "Pd"},
|
||||
#endif
|
||||
{FORMAT3(2, OP3_X(3,9), 0), "return", "p"},
|
||||
{FORMAT3(2, OP3_X(3,9), 1), "return", "q"},
|
||||
|
||||
@ -423,56 +359,48 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(0,10), 1), "umul", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,10), 0), "umulcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,10), 1), "umulcc", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(2,10), 0), "rdpr", "Ad"},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,10), 0), "rd", "Wd"},
|
||||
#endif
|
||||
/*
|
||||
* OP3 = (3,10): TCC: Trap on Integer Condition Codes
|
||||
*/
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x8)), "ta", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x8)), "ta", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x0)), "tn", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x0)), "tn", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x9)), "tne", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x9)), "tne", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x1)), "te", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x1)), "te", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xa)), "tg", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xa)), "tg", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x2)), "tle", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x2)), "tle", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xb)), "tge", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xb)), "tge", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x3)), "tl", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x3)), "tl", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xc)), "tgu", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xc)), "tgu", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x4)), "tleu", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x4)), "tleu", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xd)), "tcc", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xd)), "tcc", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x5)), "tcs", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x5)), "tcs", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xe)), "tpos", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xe)), "tpos", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x6)), "tneg", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x6)), "tneg", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0xf)), "tvc", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0xf)), "tvc", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | COND(0x7)), "tvs", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | COND(0x7)), "tvs", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x8)), "ta", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x8)), "ta", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x0)), "tn", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x0)), "tn", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x9)), "tne", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x9)), "tne", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x1)), "te", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x1)), "te", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xa)), "tg", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xa)), "tg", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x2)), "tle", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x2)), "tle", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xb)), "tge", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xb)), "tge", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x3)), "tl", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x3)), "tl", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xc)), "tgu", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xc)), "tgu", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x4)), "tleu", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x4)), "tleu", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xd)), "tcc", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xd)), "tcc", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x5)), "tcs", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x5)), "tcs", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xe)), "tpos", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xe)), "tpos", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x6)), "tneg", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x6)), "tneg", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0xf)), "tvc", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0xf)), "tvc", "0F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 0) | EIF_F4_TCOND(0x7)), "tvs", "12F"},
|
||||
{(FORMAT3(2, OP3_X(3,10), 1) | EIF_F4_TCOND(0x7)), "tvs", "0F"},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,11), 0), "smul", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,11), 1), "smul", "1id"},
|
||||
{FORMAT3(2, OP3_X(1,11), 0), "smulcc", "12d"},
|
||||
{FORMAT3(2, OP3_X(1,11), 1), "smulcc", "1id"},
|
||||
#ifdef V9
|
||||
{FORMAT3(2, OP3_X(2,11), 0), "flushw", ""},
|
||||
#else
|
||||
{FORMAT3(2, OP3_X(2,11), 0), "rd", "Td"},
|
||||
#endif
|
||||
{FORMAT3(2, OP3_X(3,11), 0), "flush", "p"},
|
||||
{FORMAT3(2, OP3_X(3,11), 1), "flush", "q"},
|
||||
|
||||
@ -570,7 +498,7 @@ struct sparc_insn sparc_i[] = {
|
||||
{FORMAT3(2, OP3_X(2,14), 1), "popc", "id"},
|
||||
|
||||
{FORMAT3(2, OP3_X(3,14), 0), "done", ""},
|
||||
{FORMAT3(2, OP3_X(3,14)|FCN(1), 1), "retry", ""},
|
||||
{FORMAT3(2, OP3_X(3,14) | EIF_F3_FCN(1), 1), "retry", ""},
|
||||
|
||||
{FORMAT3(2, OP3_X(0,15), 0), "sdiv", "12d"},
|
||||
{FORMAT3(2, OP3_X(0,15), 1), "sdiv", "1id"},
|
||||
@ -580,18 +508,18 @@ struct sparc_insn sparc_i[] = {
|
||||
* OP3 = (2,15): MOVr:
|
||||
* Move Integer Register on Register Condition
|
||||
*/
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(1)), "movrz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(1)), "movrz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(2)), "movrlez", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(2)), "movrlez", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(3)), "movrlz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(3)), "movrlz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(5)), "movrnz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(5)), "movrnz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(6)), "movrgz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(6)), "movrgz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | RCOND34(7)), "movrgez", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | RCOND34(7)), "movrgez", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(1)), "movrz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(1)), "movrz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(2)), "movrlez", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(2)), "movrlez", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(3)), "movrlz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(3)), "movrlz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(5)), "movrnz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(5)), "movrnz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(6)), "movrgz", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(6)), "movrgz", "12d"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 1) | EIF_F3_RCOND(7)), "movrgez", "1jd"},
|
||||
{(FORMAT3(2, OP3_X(2,15), 0) | EIF_F3_RCOND(7)), "movrgez", "12d"},
|
||||
|
||||
{FORMAT3(2, OP3_X(3,15), 0), "UNDEFINED", ""},
|
||||
|
||||
@ -614,10 +542,10 @@ struct sparc_insn sparc_i[] = {
|
||||
{(FORMAT3(3, OP3_X(0,1), 1)), "ldub", "qd"},
|
||||
{(FORMAT3(3, OP3_X(1,1), 0)), "lduba", "7d"},
|
||||
{(FORMAT3(3, OP3_X(1,1), 1)), "lduba", "8d"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 0) | RD(0)), "ld", "p5"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 1) | RD(0)), "ld", "q5"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 0) | RD(1)), "ldx", "p6"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 1) | RD(1)), "ldx", "q6"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 0) | EIF_F3_RD(0)), "ld", "p5"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 1) | EIF_F3_RD(0)), "ld", "q5"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 0) | EIF_F3_RD(1)), "ldx", "p6"},
|
||||
{(FORMAT3(3, OP3_X(2,1), 1) | EIF_F3_RD(1)), "ldx", "q6"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,2), 0)), "lduh", "pd"},
|
||||
{(FORMAT3(3, OP3_X(0,2), 1)), "lduh", "qd"},
|
||||
@ -652,8 +580,8 @@ struct sparc_insn sparc_i[] = {
|
||||
{(FORMAT3(3, OP3_X(1,5), 1)), "stba", "d8"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 0)), "st", "5p"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 1)), "st", "5q"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 0)|RD(1)), "stx", "6p"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 1)|RD(1)), "stx", "6q"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 0) | EIF_F3_RD(1)), "stx", "6p"},
|
||||
{(FORMAT3(3, OP3_X(2,5), 1) | EIF_F3_RD(1)), "stx", "6q"},
|
||||
|
||||
{(FORMAT3(3, OP3_X(0,6), 0)), "sth", "dp"},
|
||||
{(FORMAT3(3, OP3_X(0,6), 1)), "sth", "dq"},
|
||||
@ -825,12 +753,12 @@ struct sparc_insn sparc_i[] = {
|
||||
|
||||
/* Move F-P Register on Integer Register Condition "FMOVr" */
|
||||
/* FIXME: check for short, double, and quad's */
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(1)), "fmovre", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(2)), "fmovrlez", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(3)), "fmovrlz", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(5)), "fmovrne", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(6)), "fmovrgz", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | RCOND34(7)), "fmovrgez", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(1)), "fmovre", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(2)), "fmovrlez", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(3)), "fmovrlz", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(5)), "fmovrne", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(6)), "fmovrgz", "14e"},
|
||||
{(FORMAT3(2, OP3_X(3,5), 0) | EIF_F3_RCOND(7)), "fmovrgez", "14e"},
|
||||
#endif
|
||||
/* FP logical insns -- UltraSPARC extens */
|
||||
{(FORMAT3F(2, OP3_X(3,6), OPF_X(6,0))), "fzero", "e"},
|
||||
@ -905,21 +833,23 @@ db_disasm(loc, altfmt)
|
||||
you_lose &= (FORMAT2(0x3,0x7));
|
||||
} else {
|
||||
/* Branches */
|
||||
you_lose &= (FORMAT2(0x3,0x7)|COND(0xf));
|
||||
you_lose &= (FORMAT2(0x3,0x7) |
|
||||
EIF_F2_COND(0xf));
|
||||
}
|
||||
} else if (((bitmask>>30) & 0x3) == 0x2 &&
|
||||
((bitmask>>19) & 0x3f) == 0x34) /* XXX */ {
|
||||
/* FPop1 */
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1) | OPF(0x1ff));
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1) |
|
||||
EIF_F3_OPF(0x1ff));
|
||||
} else if (((bitmask>>30) & 0x3) == 0x2 &&
|
||||
((bitmask>>19) & 0x3f) == 0x3a) /* XXX */ {
|
||||
/* Tcc */
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1) | COND(0xf));
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1) | EIF_F4_TCOND(0xf));
|
||||
} else if (((bitmask>>30) & 0x3) == 0x2 &&
|
||||
((bitmask>>21) & 0xf) == 0x9 &&
|
||||
((bitmask>>19) & 0x3) != 0) /* XXX */ {
|
||||
/* shifts */
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1))|X(1);
|
||||
you_lose &= (FORMAT3(0x3,0x3f,0x1)) | EIF_F3_X(1);
|
||||
} else if (((bitmask>>30) & 0x3) == 0x2 &&
|
||||
((bitmask>>19) & 0x3f) == 0x2c) /* XXX */ {
|
||||
/* cmov */
|
||||
@ -953,11 +883,11 @@ db_disasm(loc, altfmt)
|
||||
for (;f_ptr < cp; f_ptr++)
|
||||
switch (*f_ptr) {
|
||||
case 'a':
|
||||
if (insn & A(1))
|
||||
if (insn & EIF_F2_A(1))
|
||||
db_printf(",a");
|
||||
break;
|
||||
case 'p':
|
||||
if (insn & P(1))
|
||||
if (insn & EIF_F2_P(1))
|
||||
db_printf(",pt");
|
||||
else
|
||||
db_printf(",pn");
|
||||
@ -992,29 +922,29 @@ db_disasm(loc, altfmt)
|
||||
break;
|
||||
case 'i':
|
||||
/* simm13 -- signed */
|
||||
val = SIGNEX(insn, 13);
|
||||
val = IF_SIMM(insn, 13);
|
||||
db_printf("%s0x%x", SIGN(val), (int)abs(val));
|
||||
break;
|
||||
case 'j':
|
||||
/* simm11 -- signed */
|
||||
val = SIGNEX(insn, 11);
|
||||
val = IF_SIMM(insn, 11);
|
||||
db_printf("%s0x%x", SIGN(val), (int)abs(val));
|
||||
break;
|
||||
case 'l':
|
||||
val = (((insn>>20)&0x3)<<13)|(insn & 0x1fff);
|
||||
val = SIGNEX(val, 16);
|
||||
val = IF_SIMM(val, 16);
|
||||
db_printsym((db_addr_t)(loc + (4 * val)), DB_STGY_ANY);
|
||||
break;
|
||||
case 'm':
|
||||
db_printsym((db_addr_t)(loc + (4 * SIGNEX(insn, 22))),
|
||||
db_printsym((db_addr_t)(loc + (4 * IF_SIMM(insn, 22))),
|
||||
DB_STGY_ANY);
|
||||
break;
|
||||
case 'u':
|
||||
db_printsym((db_addr_t)(loc + (4 * SIGNEX(insn, 19))),
|
||||
db_printsym((db_addr_t)(loc + (4 * IF_SIMM(insn, 19))),
|
||||
DB_STGY_ANY);
|
||||
break;
|
||||
case 'n':
|
||||
db_printsym((db_addr_t)(loc + (4 * SIGNEX(insn, 30))),
|
||||
db_printsym((db_addr_t)(loc + (4 * IF_SIMM(insn, 30))),
|
||||
DB_STGY_PROC);
|
||||
break;
|
||||
case 's':
|
||||
@ -1036,7 +966,7 @@ db_disasm(loc, altfmt)
|
||||
break;
|
||||
case 'q':
|
||||
case '8':
|
||||
val = SIGNEX(insn, 13);
|
||||
val = IF_SIMM(insn, 13);
|
||||
db_printf("[%%%s %c 0x%x]",
|
||||
regs[((insn >> 14) & 0x1f)],
|
||||
(int)((val<0)?'-':'+'),
|
||||
@ -1087,20 +1017,6 @@ db_disasm(loc, altfmt)
|
||||
case 'H':
|
||||
db_printf("%%%s", state_regs[((insn >> 25) & 0x1f)]);
|
||||
break;
|
||||
#ifndef V9
|
||||
case 'P':
|
||||
db_printf("%%psr");
|
||||
break;
|
||||
case 'T':
|
||||
db_printf("%%tbr");
|
||||
break;
|
||||
case 'W':
|
||||
db_printf("%%wim");
|
||||
break;
|
||||
case 'Y':
|
||||
db_printf("%%y");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
db_printf("(UNKNOWN)");
|
||||
break;
|
||||
|
298
sys/sparc64/sparc64/emul.c
Normal file
298
sys/sparc64/sparc64/emul.c
Normal file
@ -0,0 +1,298 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 by Thomas Moestl <tmm@FreeBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
#include <machine/instr.h>
|
||||
|
||||
int unaligned_fixup(struct thread *td, struct trapframe *tf);
|
||||
int emulate_insn(struct thread *td, struct trapframe *tf);
|
||||
|
||||
/*
|
||||
* Alpha-compatible sysctls to control the alignment fixup.
|
||||
*/
|
||||
static int unaligned_print = 1; /* warn about unaligned accesses */
|
||||
static int unaligned_fix = 1; /* fix up unaligned accesses */
|
||||
static int unaligned_sigbus = 0; /* don't SIGBUS on fixed-up accesses */
|
||||
|
||||
SYSCTL_INT(_machdep, OID_AUTO, unaligned_print, CTLFLAG_RW,
|
||||
&unaligned_print, 0, "");
|
||||
|
||||
SYSCTL_INT(_machdep, OID_AUTO, unaligned_fix, CTLFLAG_RW,
|
||||
&unaligned_fix, 0, "");
|
||||
|
||||
SYSCTL_INT(_machdep, OID_AUTO, unaligned_sigbus, CTLFLAG_RW,
|
||||
&unaligned_sigbus, 0, "");
|
||||
|
||||
static int
|
||||
fetch_reg(struct trapframe *tf, int reg, u_long *val)
|
||||
{
|
||||
u_long offs;
|
||||
|
||||
CTR1(KTR_TRAP, "fetch_reg: register %d", reg);
|
||||
if (reg == IREG_G0)
|
||||
*val = 0;
|
||||
else if (reg < IREG_O0) /* global */
|
||||
*val = tf->tf_global[reg];
|
||||
else if (reg < IREG_L0) /* out */
|
||||
*val = tf->tf_out[reg - IREG_O0];
|
||||
else { /* local, in */
|
||||
/*
|
||||
* The in registers are immediately after the locals in
|
||||
* the frame.
|
||||
*/
|
||||
offs = offsetof(struct frame, f_local[reg - IREG_L0]);
|
||||
return (copyin((void *)(tf->tf_sp + SPOFF + offs), val,
|
||||
sizeof(*val)));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
store_reg(struct trapframe *tf, int reg, u_long val)
|
||||
{
|
||||
u_long offs;
|
||||
|
||||
CTR1(KTR_TRAP, "store_reg: register %d", reg);
|
||||
if (reg == IREG_G0)
|
||||
return (0);
|
||||
if (reg < IREG_O0) /* global */
|
||||
tf->tf_global[reg] = val;
|
||||
else if (reg < IREG_L0) /* out */
|
||||
tf->tf_out[reg - IREG_O0] = val;
|
||||
else { /* local, in */
|
||||
/*
|
||||
* The in registers are immediately after the locals in
|
||||
* the frame.
|
||||
*/
|
||||
offs = offsetof(struct frame, f_local[reg - IREG_L0]);
|
||||
return (copyout(&val, (void *)(tf->tf_sp + SPOFF + offs),
|
||||
sizeof(val)));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Retrieve rs2 or use the immediate value from the instruction */
|
||||
static int
|
||||
f3_op2(struct trapframe *tf, u_int insn, u_long *op2)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (IF_F3_I(insn) != 0)
|
||||
*op2 = IF_SIMM(insn, 13);
|
||||
else {
|
||||
if ((error = fetch_reg(tf, IF_F3_RS2(insn), op2)) != 0)
|
||||
return (error);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: should the addr from the sfar be used instead of decoding the
|
||||
* instruction?
|
||||
*/
|
||||
static int
|
||||
f3_memop_addr(struct trapframe *tf, u_int insn, u_long *addr)
|
||||
{
|
||||
u_long addr1;
|
||||
int error;
|
||||
|
||||
if ((error = f3_op2(tf, insn, &addr1)) != 0)
|
||||
return (error);
|
||||
CTR2(KTR_TRAP, "f3_memop_addr: addr1: %#lx (imm %d)", addr1, IF_F3_I(insn));
|
||||
error = fetch_reg(tf, IF_F3_RS1(insn), addr);
|
||||
*addr += addr1;
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
fixup_st(struct trapframe *tf, u_int insn, int size)
|
||||
{
|
||||
u_long addr, reg;
|
||||
int error;
|
||||
|
||||
if ((error = f3_memop_addr(tf, insn, &addr)) != 0)
|
||||
return (error);
|
||||
if ((error = fetch_reg(tf, IF_F3_RD(insn), ®)) != 0)
|
||||
return (error);
|
||||
reg <<= 8 * (8 - size);
|
||||
CTR1(KTR_TRAP, "fixup_st: writing to %#lx", addr);
|
||||
return (copyout(®, (void *)addr, size));
|
||||
}
|
||||
|
||||
static int
|
||||
fixup_ld(struct trapframe *tf, u_int insn, int size, int sign)
|
||||
{
|
||||
u_long addr, reg;
|
||||
int error;
|
||||
|
||||
if ((error = f3_memop_addr(tf, insn, &addr)) != 0)
|
||||
return (error);
|
||||
reg = 0;
|
||||
CTR1(KTR_TRAP, "fixup_ld: reading from %#lx", addr);
|
||||
if ((error = copyin((void *)addr, ®, size)) != 0)
|
||||
return (error);
|
||||
reg >>= 8 * (8 - size);
|
||||
if (sign && size < 8) {
|
||||
/* Need to sign-extend. */
|
||||
reg = IF_SEXT(reg, size * 8);
|
||||
}
|
||||
return (store_reg(tf, IF_F3_RD(insn), reg));
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: fixed up loads and stores are not atomical any more (in some cases,
|
||||
* they could be made, though, but that is not implemented yet). This means
|
||||
* that in some sorts of programs, this emulation could cause bugs.
|
||||
* XXX: this is still very incomplete!
|
||||
*/
|
||||
int
|
||||
unaligned_fixup(struct thread *td, struct trapframe *tf)
|
||||
{
|
||||
struct mmuframe *mf;
|
||||
struct proc *p;
|
||||
u_int insn;
|
||||
int fixed, error;
|
||||
|
||||
p = td->td_proc;
|
||||
mf = (struct mmuframe *)tf->tf_arg;
|
||||
|
||||
if (rwindow_save(td) != 0) {
|
||||
/*
|
||||
* The process will need to be killed without sending a
|
||||
* signal; let the signal code do that.
|
||||
*/
|
||||
return (SIGBUS);
|
||||
}
|
||||
if (copyin((void *)tf->tf_tpc, &insn, sizeof(insn)) != 0)
|
||||
return (SIGBUS);
|
||||
|
||||
CTR1(KTR_TRAP, "unaligned_fixup: insn %x", insn);
|
||||
fixed = 0;
|
||||
if (unaligned_fix) {
|
||||
error = 0;
|
||||
if (IF_OP(insn) == IOP_LDST) {
|
||||
fixed = 1;
|
||||
switch (IF_F3_OP3(insn)) {
|
||||
case INS3_LDUH:
|
||||
error = fixup_ld(tf, insn, 2, 0);
|
||||
break;
|
||||
case INS3_LDUW:
|
||||
error = fixup_ld(tf, insn, 4, 0);
|
||||
break;
|
||||
case INS3_LDX:
|
||||
error = fixup_ld(tf, insn, 8, 0);
|
||||
break;
|
||||
case INS3_LDSH:
|
||||
error = fixup_ld(tf, insn, 2, 1);
|
||||
break;
|
||||
case INS3_LDSW:
|
||||
error = fixup_ld(tf, insn, 4, 1);
|
||||
break;
|
||||
case INS3_STH:
|
||||
error = fixup_st(tf, insn, 2);
|
||||
break;
|
||||
case INS3_STW:
|
||||
error = fixup_st(tf, insn, 4);
|
||||
break;
|
||||
case INS3_STX:
|
||||
error = fixup_st(tf, insn, 8);
|
||||
break;
|
||||
default:
|
||||
fixed = 0;
|
||||
}
|
||||
}
|
||||
if (error != 0)
|
||||
return (SIGBUS);
|
||||
}
|
||||
|
||||
CTR5(KTR_TRAP, "unaligned_fixup: pid %d, va=%#lx pc=%#lx "
|
||||
"npc=%#lx, fixed=%d", p->p_pid, mf->mf_sfar, tf->tf_tpc,
|
||||
tf->tf_tnpc, fixed);
|
||||
if (unaligned_print || !fixed) {
|
||||
uprintf("pid %d (%s): unaligned access: va=%#lx pc=%#lx "
|
||||
"npc=%#lx %s\n", p->p_pid, p->p_comm, mf->mf_sfar,
|
||||
tf->tf_tpc, tf->tf_tnpc, fixed ? "(fixed)" : "(unfixable)");
|
||||
}
|
||||
return (fixed && !unaligned_sigbus ? 0 : SIGBUS);
|
||||
}
|
||||
|
||||
static int
|
||||
emul_popc(struct trapframe *tf, u_int insn)
|
||||
{
|
||||
u_long reg, res;
|
||||
int i;
|
||||
|
||||
if (IF_F3_RS1(insn) != 0)
|
||||
return (SIGILL);
|
||||
if (f3_op2(tf, insn, ®) != 0)
|
||||
return (SIGBUS);
|
||||
res = 0;
|
||||
for (i = 0; i < 64; i++)
|
||||
res += (reg >> i) & 1;
|
||||
if (store_reg(tf, IF_F3_RD(insn), res) != 0)
|
||||
return (SIGBUS);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Emulate unimplemented instructions, if applicable.
|
||||
* Only handles popc right now.
|
||||
*/
|
||||
int
|
||||
emulate_insn(struct thread *td, struct trapframe *tf)
|
||||
{
|
||||
u_int insn;
|
||||
|
||||
if (rwindow_save(td) != 0) {
|
||||
/*
|
||||
* The process will need to be killed without sending a
|
||||
* signal; let the signal code do that.
|
||||
*/
|
||||
return (SIGBUS);
|
||||
}
|
||||
if (copyin((void *)tf->tf_tpc, &insn, sizeof(insn)) != 0)
|
||||
return (SIGBUS);
|
||||
|
||||
CTR1(KTR_TRAP, "emulate_insn: insn %x", insn);
|
||||
switch (IF_OP(insn)) {
|
||||
case IOP_MISC:
|
||||
switch (IF_F3_OP3(insn)) {
|
||||
case INS2_POPC:
|
||||
return (emul_popc(tf, insn));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (SIGILL);
|
||||
}
|
@ -126,6 +126,9 @@ const char *trap_msg[] = {
|
||||
"trap instruction",
|
||||
};
|
||||
|
||||
int unaligned_fixup(struct thread *td, struct trapframe *tf);
|
||||
int emulate_insn(struct thread *td, struct trapframe *tf);
|
||||
|
||||
void
|
||||
trap(struct trapframe *tf)
|
||||
{
|
||||
@ -175,6 +178,11 @@ trap(struct trapframe *tf)
|
||||
* User Mode Traps
|
||||
*/
|
||||
case T_ALIGN:
|
||||
if ((sig = unaligned_fixup(td, tf)) == 0) {
|
||||
TF_DONE(tf);
|
||||
goto user;
|
||||
}
|
||||
goto trapsig;
|
||||
case T_ALIGN_LDDF:
|
||||
case T_ALIGN_STDF:
|
||||
sig = SIGBUS;
|
||||
@ -222,7 +230,10 @@ trap(struct trapframe *tf)
|
||||
}
|
||||
goto userout;
|
||||
case T_INSN_ILLEGAL:
|
||||
sig = SIGILL;
|
||||
if ((sig = emulate_insn(td, tf)) == 0) {
|
||||
TF_DONE(tf);
|
||||
goto user;
|
||||
}
|
||||
goto trapsig;
|
||||
case T_PRIV_ACTION:
|
||||
case T_PRIV_OPCODE:
|
||||
@ -521,8 +532,7 @@ syscall(struct trapframe *tf)
|
||||
* (usually), instead we need to advance one instruction.
|
||||
*/
|
||||
tpc = tf->tf_tpc;
|
||||
tf->tf_tpc = tf->tf_tnpc;
|
||||
tf->tf_tnpc += 4;
|
||||
TF_DONE(tf);
|
||||
|
||||
if (p->p_sysent->sv_prepsyscall) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user