Commit b48cfdffd9f15432355c8e4ed9d2781eab9e4358
1 parent
2423f660
Throw RI for invalid MFMC0-class instructions. Introduce optional
MIPS_STRICT_STANDARD define to adhere more to the spec than it makes sense in normal operation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2650 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
18 additions
and
3 deletions
target-mips/mips-defs.h
| @@ -19,4 +19,9 @@ | @@ -19,4 +19,9 @@ | ||
| 19 | #define TARGET_LONG_BITS 32 | 19 | #define TARGET_LONG_BITS 32 |
| 20 | #endif | 20 | #endif |
| 21 | 21 | ||
| 22 | +/* Strictly follow the architecture standard: Disallow "special" | ||
| 23 | + instruction handling for PMON/SPIM, force cycle-dependent | ||
| 24 | + Count/Compare maintenance. */ | ||
| 25 | +//#define MIPS_STRICT_STANDARD 1 | ||
| 26 | + | ||
| 22 | #endif /* !defined (__QEMU_MIPS_DEFS_H__) */ | 27 | #endif /* !defined (__QEMU_MIPS_DEFS_H__) */ |
target-mips/translate.c
| @@ -305,7 +305,7 @@ enum { | @@ -305,7 +305,7 @@ enum { | ||
| 305 | }; | 305 | }; |
| 306 | 306 | ||
| 307 | /* MFMC0 opcodes */ | 307 | /* MFMC0 opcodes */ |
| 308 | -#define MASK_MFMC0(op) MASK_CP0(op) | (op & ((0x0C << 11) | (1 << 5))) | 308 | +#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF) |
| 309 | 309 | ||
| 310 | enum { | 310 | enum { |
| 311 | OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, | 311 | OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0, |
| @@ -4715,8 +4715,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4715,8 +4715,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
| 4715 | case OPC_MTLO: /* Move to HI/LO */ | 4715 | case OPC_MTLO: /* Move to HI/LO */ |
| 4716 | gen_HILO(ctx, op1, rs); | 4716 | gen_HILO(ctx, op1, rs); |
| 4717 | break; | 4717 | break; |
| 4718 | - case OPC_PMON: /* Pmon entry point */ | 4718 | + case OPC_PMON: /* Pmon entry point, also R4010 selsl */ |
| 4719 | +#ifdef MIPS_STRICT_STANDARD | ||
| 4720 | + MIPS_INVAL("PMON / selsl"); | ||
| 4721 | + generate_exception(ctx, EXCP_RI); | ||
| 4722 | +#else | ||
| 4719 | gen_op_pmon(sa); | 4723 | gen_op_pmon(sa); |
| 4724 | +#endif | ||
| 4720 | break; | 4725 | break; |
| 4721 | case OPC_SYSCALL: | 4726 | case OPC_SYSCALL: |
| 4722 | generate_exception(ctx, EXCP_SYSCALL); | 4727 | generate_exception(ctx, EXCP_SYSCALL); |
| @@ -4724,10 +4729,15 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4724,10 +4729,15 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
| 4724 | case OPC_BREAK: | 4729 | case OPC_BREAK: |
| 4725 | generate_exception(ctx, EXCP_BREAK); | 4730 | generate_exception(ctx, EXCP_BREAK); |
| 4726 | break; | 4731 | break; |
| 4727 | - case OPC_SPIM: /* SPIM ? */ | 4732 | + case OPC_SPIM: |
| 4733 | +#ifdef MIPS_STRICT_STANDARD | ||
| 4734 | + MIPS_INVAL("SPIM"); | ||
| 4735 | + generate_exception(ctx, EXCP_RI); | ||
| 4736 | +#else | ||
| 4728 | /* Implemented as RI exception for now. */ | 4737 | /* Implemented as RI exception for now. */ |
| 4729 | MIPS_INVAL("spim (unofficial)"); | 4738 | MIPS_INVAL("spim (unofficial)"); |
| 4730 | generate_exception(ctx, EXCP_RI); | 4739 | generate_exception(ctx, EXCP_RI); |
| 4740 | +#endif | ||
| 4731 | break; | 4741 | break; |
| 4732 | case OPC_SYNC: | 4742 | case OPC_SYNC: |
| 4733 | /* Treat as a noop. */ | 4743 | /* Treat as a noop. */ |