summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortmm <tmm@FreeBSD.org>2001-11-06 20:13:44 +0000
committertmm <tmm@FreeBSD.org>2001-11-06 20:13:44 +0000
commit594c8e829ba40deb4c6ba3f1cac483af55625718 (patch)
tree7cf05885f0a2ec73b1bb39d8ef6a5fe58c444e0b /sys
parentbd13886bd85b6d5cac62ae81da44b43eeae279de (diff)
downloadFreeBSD-src-594c8e829ba40deb4c6ba3f1cac483af55625718.zip
FreeBSD-src-594c8e829ba40deb4c6ba3f1cac483af55625718.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/include/frame.h5
-rw-r--r--sys/sparc64/include/instr.h620
-rw-r--r--sys/sparc64/sparc64/db_disasm.c402
-rw-r--r--sys/sparc64/sparc64/emul.c298
-rw-r--r--sys/sparc64/sparc64/trap.c16
5 files changed, 1095 insertions, 246 deletions
diff --git a/sys/sparc64/include/frame.h b/sys/sparc64/include/frame.h
index 5151ef2..d297d4e 100644
--- a/sys/sparc64/include/frame.h
+++ b/sys/sparc64/include/frame.h
@@ -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;
diff --git a/sys/sparc64/include/instr.h b/sys/sparc64/include/instr.h
new file mode 100644
index 0000000..b6a8ec1
--- /dev/null
+++ b/sys/sparc64/include/instr.h
@@ -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_ */
diff --git a/sys/sparc64/sparc64/db_disasm.c b/sys/sparc64/sparc64/db_disasm.c
index eb157c8..532fd82 100644
--- a/sys/sparc64/sparc64/db_disasm.c
+++ b/sys/sparc64/sparc64/db_disasm.c
@@ -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;
diff --git a/sys/sparc64/sparc64/emul.c b/sys/sparc64/sparc64/emul.c
new file mode 100644
index 0000000..a46f206
--- /dev/null
+++ b/sys/sparc64/sparc64/emul.c
@@ -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);
+}
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index bf99279..032ca2a 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -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) {
/*
OpenPOWER on IntegriCloud