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:
Thomas Moestl 2001-11-06 20:13:44 +00:00
parent d3c9fa0463
commit 9b3b51bcab
5 changed files with 1095 additions and 246 deletions

View File

@ -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
View 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_ */

View File

@ -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
View 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), &reg)) != 0)
return (error);
reg <<= 8 * (8 - size);
CTR1(KTR_TRAP, "fixup_st: writing to %#lx", addr);
return (copyout(&reg, (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, &reg, 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, &reg) != 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);
}

View File

@ -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) {
/*