From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1DPSAA-0004Aq-Gx for qemu-devel@nongnu.org; Sat, 23 Apr 2005 17:27:42 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1DPSA9-0004AP-Fy for qemu-devel@nongnu.org; Sat, 23 Apr 2005 17:27:42 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DPSA9-0003gb-9Z for qemu-devel@nongnu.org; Sat, 23 Apr 2005 17:27:41 -0400 Received: from [65.74.133.9] (helo=mail.codesourcery.com) by monty-python.gnu.org with esmtp (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA:24) (Exim 4.34) id 1DPRw1-0006EV-8X for qemu-devel@nongnu.org; Sat, 23 Apr 2005 17:13:05 -0400 From: Paul Brook Date: Sat, 23 Apr 2005 22:09:47 +0100 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_bmraCJQ+hoM57w0" Message-Id: <200504232209.47652.paul@codesourcery.com> Subject: [Qemu-devel] [patch] Remove switch statements from op.c Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --Boundary-00=_bmraCJQ+hoM57w0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline The i386 target uses switch statements in op.c. GCC implements these with jump tables on arm hosts. Dyngen can't grok jump tables. There's no easy way to figure out what is a jump table entry and what is an instruction. The attached patch replaces the switch statements with a direct table lookup. Paul --Boundary-00=_bmraCJQ+hoM57w0 Content-Type: text/x-diff; charset="us-ascii"; name="patch.qemu_noswitch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch.qemu_noswitch" Index: target-i386/op.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-i386/op.c,v retrieving revision 1.36 diff -u -p -r1.36 op.c --- target-i386/op.c 20 Mar 2005 10:39:24 -0000 1.36 +++ target-i386/op.c 23 Apr 2005 20:59:45 -0000 @@ -1952,94 +1952,48 @@ void OPPROTO op_fxchg_ST0_STN(void) /* FPU operations */ +const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; + void OPPROTO op_fcom_ST0_FT0(void) { - int cc; - switch(floatx_compare(ST0, FT0, &env->fp_status)) { - case -1: - cc = 0x0100; - break; - case 0: - cc = 0x4000; - break; - case 1: - cc = 0x0000; - break; - case 2: - default: - cc = 0x4500; - break; - } - env->fpus = (env->fpus & ~0x4500) | cc; + int ret; + + ret = floatx_compare(ST0, FT0, &env->fp_status); + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; FORCE_RET(); } void OPPROTO op_fucom_ST0_FT0(void) { - int cc; - switch(floatx_compare_quiet(ST0, FT0, &env->fp_status)) { - case -1: - cc = 0x0100; - break; - case 0: - cc = 0x4000; - break; - case 1: - cc = 0x0000; - break; - case 2: - default: - cc = 0x4500; - break; - } - env->fpus = (env->fpus & ~0x4500) | cc; + int ret; + + ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; FORCE_RET(); } +const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; + void OPPROTO op_fcomi_ST0_FT0(void) { - int eflags, cc; - switch(floatx_compare(ST0, FT0, &env->fp_status)) { - case -1: - cc = CC_C; - break; - case 0: - cc = CC_Z; - break; - case 1: - cc = 0; - break; - case 2: - default: - cc = CC_Z | CC_P | CC_C; - break; - } + int eflags; + int ret; + + ret = floatx_compare(ST0, FT0, &env->fp_status); eflags = cc_table[CC_OP].compute_all(); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc; + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; CC_SRC = eflags; FORCE_RET(); } void OPPROTO op_fucomi_ST0_FT0(void) { - int eflags, cc; - switch(floatx_compare_quiet(ST0, FT0, &env->fp_status)) { - case -1: - cc = CC_C; - break; - case 0: - cc = CC_Z; - break; - case 1: - cc = 0; - break; - case 2: - default: - cc = CC_Z | CC_P | CC_C; - break; - } + int eflags; + int ret; + + ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); eflags = cc_table[CC_OP].compute_all(); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc; + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; CC_SRC = eflags; FORCE_RET(); } Index: target-i386/ops_sse.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-i386/ops_sse.h,v retrieving revision 1.5 diff -u -p -r1.5 ops_sse.h --- target-i386/ops_sse.h 20 Mar 2005 10:39:24 -0000 1.5 +++ target-i386/ops_sse.h 23 Apr 2005 20:59:45 -0000 @@ -1079,9 +1079,11 @@ SSE_OP_CMP(cmpnlt, FPU_CMPNLT) SSE_OP_CMP(cmpnle, FPU_CMPNLE) SSE_OP_CMP(cmpord, FPU_CMPORD) +const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; + void OPPROTO op_ucomiss(void) { - int eflags; + int ret; float32 s0, s1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1089,28 +1091,14 @@ void OPPROTO op_ucomiss(void) s0 = d->XMM_S(0); s1 = s->XMM_S(0); - switch(float32_compare_quiet(s0, s1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float32_compare_quiet(s0, s1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); } void OPPROTO op_comiss(void) { - int eflags; + int ret; float32 s0, s1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1118,28 +1106,14 @@ void OPPROTO op_comiss(void) s0 = d->XMM_S(0); s1 = s->XMM_S(0); - switch(float32_compare(s0, s1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float32_compare(s0, s1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); } void OPPROTO op_ucomisd(void) { - int eflags; + int ret; float64 d0, d1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1147,28 +1121,14 @@ void OPPROTO op_ucomisd(void) d0 = d->XMM_D(0); d1 = s->XMM_D(0); - switch(float64_compare_quiet(d0, d1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float64_compare_quiet(d0, d1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); } void OPPROTO op_comisd(void) { - int eflags; + int ret; float64 d0, d1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1176,22 +1136,8 @@ void OPPROTO op_comisd(void) d0 = d->XMM_D(0); d1 = s->XMM_D(0); - switch(float64_compare(d0, d1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float64_compare(d0, d1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); } --Boundary-00=_bmraCJQ+hoM57w0--