From owner-svn-src-all@FreeBSD.ORG Mon Mar 15 18:33:33 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 14E2F106566B; Mon, 15 Mar 2010 18:33:33 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 029F78FC19; Mon, 15 Mar 2010 18:33:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2FIXW2U042533; Mon, 15 Mar 2010 18:33:32 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2FIXWf4042530; Mon, 15 Mar 2010 18:33:32 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201003151833.o2FIXWf4042530@svn.freebsd.org> From: Marius Strobl Date: Mon, 15 Mar 2010 18:33:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-6@freebsd.org X-SVN-Group: stable-6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205185 - stable/6/lib/libc/sparc64/fpu X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Mar 2010 18:33:33 -0000 Author: marius Date: Mon Mar 15 18:33:32 2010 New Revision: 205185 URL: http://svn.freebsd.org/changeset/base/205185 Log: MFC: r204974, r205002 - The OPSZ macro actually only does the right thing for int32 and int64 operands but not for double and extended double ones. Instead of trying to fix the macro just nuke it and unroll the loops in the correct way though as extended double operands turn out to be the only special case. - For FxTO{s,d,q} the source operand is int64 so rs2 has to be re-decoded after setting type accordingly as it's generally decoded using the low 2 bits as the type, which are 0 for these three instructions. - Similarly, in case of F{s,d,q}TOx the target is int64 so rd has to be re-decoded using not only the operand mask appropriate for int64 but also the correct register number encoding. - Use const where appropriate. - Wrap long lines. Submitted by: Peter Jeremy (partly) Modified: stable/6/lib/libc/sparc64/fpu/fpu.c stable/6/lib/libc/sparc64/fpu/fpu_emu.h Directory Properties: stable/6/lib/libc/ (props changed) Modified: stable/6/lib/libc/sparc64/fpu/fpu.c ============================================================================== --- stable/6/lib/libc/sparc64/fpu/fpu.c Mon Mar 15 18:33:23 2010 (r205184) +++ stable/6/lib/libc/sparc64/fpu/fpu.c Mon Mar 15 18:33:32 2010 (r205185) @@ -101,7 +101,7 @@ __FBSDID("$FreeBSD$"); #define X8(x) X4(x),X4(x) #define X16(x) X8(x),X8(x) -static char cx_to_trapx[] = { +static const char cx_to_trapx[] = { X1(FSR_NX), X2(FSR_DZ), X4(FSR_UF), @@ -117,7 +117,8 @@ int __fpe_debug = 0; #endif #endif /* FPU_DEBUG */ -static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t, u_long); +static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t, + u_long); /* * Need to use an fpstate on the stack; we could switch, so we cannot safely @@ -173,7 +174,7 @@ __fpu_exception(struct utrapframe *uf) void __fpu_dumpfpn(struct fpn *fp) { - static char *class[] = { + static const char *const class[] = { "SNAN", "QNAN", "ZERO", "NUM", "INF" }; @@ -185,15 +186,11 @@ __fpu_dumpfpn(struct fpn *fp) } #endif -static int opmask[] = {0, 0, 1, 3}; +static const int opmask[] = {0, 0, 1, 3, 1}; /* Decode 5 bit register field depending on the type. */ #define RN_DECODE(tp, rn) \ - ((tp == FTYPE_DBL || tp == FTYPE_EXT ? INSFPdq_RN((rn)) : (rn)) & \ - ~opmask[tp]) - -/* Operand size in 32-bit registers. */ -#define OPSZ(tp) ((tp) == FTYPE_LNG ? 2 : (1 << (tp))) + ((tp) >= FTYPE_DBL ? INSFPdq_RN(rn) & ~opmask[tp] : (rn)) /* * Helper for forming the below case statements. Build only the op3 and opf @@ -213,8 +210,6 @@ static void __fpu_mov(struct fpemu *fe, int type, int rd, int rs2, u_int32_t nand, u_int32_t xor) { - u_int64_t tmp64; - int i; if (type == FTYPE_INT || type == FTYPE_SNG) __fpu_setreg(rd, (__fpu_getreg(rs2) & ~nand) ^ xor); @@ -223,13 +218,10 @@ __fpu_mov(struct fpemu *fe, int type, in * Need to use the double versions to be able to access * the upper 32 fp registers. */ - for (i = 0; i < OPSZ(type); i += 2, rd += 2, rs2 += 2) { - tmp64 = __fpu_getreg64(rs2); - if (i == 0) - tmp64 = (tmp64 & ~((u_int64_t)nand << 32)) ^ - ((u_int64_t)xor << 32); - __fpu_setreg64(rd, tmp64); - } + __fpu_setreg64(rd, (__fpu_getreg64(rs2) & + ~((u_int64_t)nand << 32)) ^ ((u_int64_t)xor << 32)); + if (type == FTYPE_EXT) + __fpu_setreg64(rd + 2, __fpu_getreg64(rs2 + 2)); } } @@ -275,17 +267,17 @@ __fpu_cmpck(struct fpemu *fe) * multiply two integers this way. */ static int -__fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, u_long tstate) +__fpu_execute(struct utrapframe *uf, struct fpemu *fe, u_int32_t insn, + u_long tstate) { struct fpn *fp; int opf, rs1, rs2, rd, type, mask, cx, cond; u_long reg, fsr; u_int space[4]; - int i; /* * `Decode' and execute instruction. Start with no exceptions. - * The type of any opf opcode is in the bottom two bits, so we + * The type of almost any OPF opcode is in the bottom two bits, so we * squish them out here. */ opf = insn & (IF_MASK(IF_F3_OP3_SHIFT, IF_F3_OP3_BITS) | @@ -363,7 +355,7 @@ __fpu_execute(struct utrapframe *uf, str __fpu_explode(fe, &fe->fe_f2, type, rs2); __fpu_compare(fe, 1, IF_F3_CC(insn)); return (__fpu_cmpck(fe)); - case FOP(INS2_FPop1, INSFP1_FMOV): /* these should all be pretty obvious */ + case FOP(INS2_FPop1, INSFP1_FMOV): __fpu_mov(fe, type, rd, rs2, 0, 0); return (0); case FOP(INS2_FPop1, INSFP1_FNEG): @@ -414,6 +406,7 @@ __fpu_execute(struct utrapframe *uf, str case FOP(INS2_FPop1, INSFP1_FxTOd): case FOP(INS2_FPop1, INSFP1_FxTOq): type = FTYPE_LNG; + rs2 = RN_DECODE(type, IF_F3_RS2(insn)); __fpu_explode(fe, fp = &fe->fe_f1, type, rs2); /* sneaky; depends on instruction encoding */ type = (IF_F3_OPF(insn) >> 2) & 3; @@ -422,8 +415,7 @@ __fpu_execute(struct utrapframe *uf, str case FOP(INS2_FPop1, INSFP1_FTOx): __fpu_explode(fe, fp = &fe->fe_f1, type, rs2); type = FTYPE_LNG; - mask = 1; /* needs 2 registers */ - rd = IF_F3_RD(insn) & ~mask; + rd = RN_DECODE(type, IF_F3_RD(insn)); break; case FOP(INS2_FPop1, INSFP1_FTOs): case FOP(INS2_FPop1, INSFP1_FTOd): @@ -461,10 +453,10 @@ __fpu_execute(struct utrapframe *uf, str if (type == FTYPE_INT || type == FTYPE_SNG) __fpu_setreg(rd, space[0]); else { - for (i = 0; i < OPSZ(type); i += 2) { - __fpu_setreg64(rd + i, ((u_int64_t)space[i] << 32) | - space[i + 1]); - } + __fpu_setreg64(rd, ((u_int64_t)space[0] << 32) | space[1]); + if (type == FTYPE_EXT) + __fpu_setreg64(rd + 2, + ((u_int64_t)space[2] << 32) | space[3]); } return (0); /* success */ } Modified: stable/6/lib/libc/sparc64/fpu/fpu_emu.h ============================================================================== --- stable/6/lib/libc/sparc64/fpu/fpu_emu.h Mon Mar 15 18:33:23 2010 (r205184) +++ stable/6/lib/libc/sparc64/fpu/fpu_emu.h Mon Mar 15 18:33:32 2010 (r205185) @@ -149,7 +149,7 @@ struct fpn { #define FTYPE_SNG INSFP_s #define FTYPE_DBL INSFP_d #define FTYPE_EXT INSFP_q -#define FTYPE_LNG -1 +#define FTYPE_LNG 4 /* * Emulator state.