On Fri, Mar 30, 2007 at 07:18:28PM +0200, Aurelien Jarno wrote: > Hi all, > > Both of the SPARC CPU currently emulated in QEMU do not have a > coprocessor. In such case executing a Cpop1 or a Cpop2 instruction > should generate a cp_disabled trap, but the current implementation > generates a illegal_instruction instead. >
This is actually wrong for the SPARCv9 target. Those instructions have been removed from the SPARCv9 instruction set, so they should generate an illegal_instruction trap on SPARCv9 and a cp_disabled trap on SPARCv8. The patch below is now correct. It also does the same for LDC* and STC* instructions. Index: target-sparc/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v retrieving revision 1.30 diff -u -d -p -r1.30 cpu.h --- target-sparc/cpu.h 25 Mar 2007 07:55:52 -0000 1.30 +++ target-sparc/cpu.h 31 Mar 2007 12:29:24 -0000 @@ -40,6 +40,7 @@ #define TT_TOVF 0x0a #define TT_EXTINT 0x10 #define TT_DIV_ZERO 0x2a +#define TT_NCP_INSN 0x24 #define TT_TRAP 0x80 #else #define TT_TFAULT 0x08 Index: target-sparc/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-sparc/translate.c,v retrieving revision 1.38 diff -u -d -p -r1.38 translate.c --- target-sparc/translate.c 25 Mar 2007 07:55:52 -0000 1.38 +++ target-sparc/translate.c 31 Mar 2007 12:29:25 -0000 @@ -1736,7 +1739,7 @@ static void disas_sparc_insn(DisasContex gen_op_sra(); gen_movl_T0_reg(rd); #endif - } else if (xop < 0x38) { + } else if (xop < 0x36) { rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ @@ -2142,6 +2145,12 @@ static void disas_sparc_insn(DisasContex goto illegal_insn; } } + } else if (xop == 0x36 || xop == 0x37) { /* CPop1 & CPop2, V9 impdep1 & impdep2 */ +#ifdef TARGET_SPARC64 + goto illegal_insn; +#else + goto ncp_insn; +#endif #ifdef TARGET_SPARC64 } else if (xop == 0x39) { /* V9 return */ rs1 = GET_FIELD(insn, 13, 17); @@ -2390,6 +2415,17 @@ static void disas_sparc_insn(DisasContex break; #ifndef TARGET_SPARC64 + case 0x30: /* ldc */ + case 0x31: /* ldcsr */ + case 0x33: /* lddc */ + case 0x34: /* stc */ + case 0x35: /* stcsr */ + case 0x36: /* stdcq */ + case 0x37: /* stdc */ + goto ncp_insn; + break; +#endif +#ifndef TARGET_SPARC64 /* avoid warnings */ (void) &gen_op_stfa; (void) &gen_op_stdfa; @@ -2598,6 +2648,12 @@ static void disas_sparc_insn(DisasContex save_state(dc); gen_op_fpexception_im(FSR_FTT_UNIMPFPOP); dc->is_br = 1; +#ifndef TARGET_SPARC64 + ncp_insn: + save_state(dc); + gen_op_exception(TT_NCP_INSN); + dc->is_br = 1; +#endif } static inline int gen_intermediate_code_internal(TranslationBlock * tb, -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `- people.debian.org/~aurel32 | www.aurel32.net