Revision 36d23958 target-mips/translate.c
b/target-mips/translate.c | ||
---|---|---|
391 | 391 |
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr); |
392 | 392 |
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr); |
393 | 393 |
|
394 |
#ifdef MIPS_USES_FPU |
|
395 |
|
|
396 | 394 |
static const char *fregnames[] = |
397 | 395 |
{ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
398 | 396 |
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", |
... | ... | |
476 | 474 |
FOP_CONDS(d) |
477 | 475 |
FOP_CONDS(s) |
478 | 476 |
|
479 |
#endif /* MIPS_USES_FPU */ |
|
480 |
|
|
481 | 477 |
typedef struct DisasContext { |
482 | 478 |
struct TranslationBlock *tb; |
483 | 479 |
target_ulong pc, saved_pc; |
... | ... | |
640 | 636 |
OP_ST_TABLE(b); |
641 | 637 |
OP_LD_TABLE(l); |
642 | 638 |
OP_ST_TABLE(c); |
643 |
#ifdef MIPS_USES_FPU |
|
644 | 639 |
OP_LD_TABLE(wc1); |
645 | 640 |
OP_ST_TABLE(wc1); |
646 | 641 |
OP_LD_TABLE(dc1); |
647 | 642 |
OP_ST_TABLE(dc1); |
648 |
#endif |
|
649 | 643 |
|
650 | 644 |
/* Load and store */ |
651 | 645 |
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
... | ... | |
794 | 788 |
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); |
795 | 789 |
} |
796 | 790 |
|
797 |
#ifdef MIPS_USES_FPU |
|
798 |
|
|
799 | 791 |
/* Load and store */ |
800 | 792 |
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, |
801 | 793 |
int base, int16_t offset) |
... | ... | |
843 | 835 |
MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); |
844 | 836 |
} |
845 | 837 |
|
846 |
#endif /* MIPS_USES_FPU */ |
|
847 |
|
|
848 | 838 |
/* Arithmetic with immediate operand */ |
849 | 839 |
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, |
850 | 840 |
int rs, int16_t imm) |
... | ... | |
4111 | 4101 |
MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); |
4112 | 4102 |
} |
4113 | 4103 |
|
4114 |
#ifdef MIPS_USES_FPU |
|
4115 |
|
|
4116 | 4104 |
/* CP1 Branches (before delay slot) */ |
4117 | 4105 |
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, |
4118 | 4106 |
int32_t offset) |
... | ... | |
4531 | 4519 |
gen_op_movt(ccbit, rd, rs); |
4532 | 4520 |
} |
4533 | 4521 |
|
4534 |
#endif /* MIPS_USES_FPU */ |
|
4535 |
|
|
4536 | 4522 |
/* ISA extensions (ASEs) */ |
4537 | 4523 |
/* MIPS16 extension to MIPS32 */ |
4538 | 4524 |
/* SmartMIPS extension to MIPS32 */ |
... | ... | |
4555 | 4541 |
gen_set_label(l1); |
4556 | 4542 |
} |
4557 | 4543 |
|
4558 |
static void decode_opc (DisasContext *ctx) |
|
4544 |
static void decode_opc (CPUState *env, DisasContext *ctx)
|
|
4559 | 4545 |
{ |
4560 | 4546 |
int32_t offset; |
4561 | 4547 |
int rs, rt, rd, sa; |
... | ... | |
4631 | 4617 |
/* Treat as a noop. */ |
4632 | 4618 |
break; |
4633 | 4619 |
|
4634 |
#ifdef MIPS_USES_FPU |
|
4635 | 4620 |
case OPC_MOVCI: |
4636 |
gen_op_cp1_enabled(); |
|
4637 |
gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, |
|
4638 |
(ctx->opcode >> 16) & 1); |
|
4621 |
if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
|
4622 |
gen_op_cp1_enabled(); |
|
4623 |
gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, |
|
4624 |
(ctx->opcode >> 16) & 1); |
|
4625 |
} else { |
|
4626 |
generate_exception(ctx, EXCP_RI); |
|
4627 |
} |
|
4639 | 4628 |
break; |
4640 |
#endif |
|
4641 | 4629 |
|
4642 | 4630 |
#ifdef MIPS_HAS_MIPS64 |
4643 | 4631 |
/* MIPS64 specific opcodes */ |
... | ... | |
4868 | 4856 |
case OPC_LDC1: |
4869 | 4857 |
case OPC_SWC1: |
4870 | 4858 |
case OPC_SDC1: |
4871 |
#if defined(MIPS_USES_FPU)
|
|
4872 |
save_cpu_state(ctx, 1); |
|
4873 |
gen_op_cp1_enabled(); |
|
4874 |
gen_flt_ldst(ctx, op, rt, rs, imm); |
|
4875 |
#else
|
|
4876 |
generate_exception_err(ctx, EXCP_CpU, 1); |
|
4877 |
#endif
|
|
4859 |
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
|
4860 |
save_cpu_state(ctx, 1);
|
|
4861 |
gen_op_cp1_enabled();
|
|
4862 |
gen_flt_ldst(ctx, op, rt, rs, imm);
|
|
4863 |
} else {
|
|
4864 |
generate_exception_err(ctx, EXCP_CpU, 1);
|
|
4865 |
}
|
|
4878 | 4866 |
break; |
4879 | 4867 |
|
4880 | 4868 |
case OPC_CP1: |
4881 |
#if defined(MIPS_USES_FPU)
|
|
4882 |
save_cpu_state(ctx, 1); |
|
4883 |
gen_op_cp1_enabled(); |
|
4884 |
op1 = MASK_CP1(ctx->opcode); |
|
4885 |
switch (op1) { |
|
4886 |
case OPC_MFC1: |
|
4887 |
case OPC_CFC1: |
|
4888 |
case OPC_MTC1: |
|
4889 |
case OPC_CTC1: |
|
4869 |
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
|
4870 |
save_cpu_state(ctx, 1);
|
|
4871 |
gen_op_cp1_enabled();
|
|
4872 |
op1 = MASK_CP1(ctx->opcode);
|
|
4873 |
switch (op1) {
|
|
4874 |
case OPC_MFC1:
|
|
4875 |
case OPC_CFC1:
|
|
4876 |
case OPC_MTC1:
|
|
4877 |
case OPC_CTC1:
|
|
4890 | 4878 |
#ifdef MIPS_HAS_MIPS64 |
4891 |
case OPC_DMFC1: |
|
4892 |
case OPC_DMTC1: |
|
4879 |
case OPC_DMFC1:
|
|
4880 |
case OPC_DMTC1:
|
|
4893 | 4881 |
#endif |
4894 |
gen_cp1(ctx, op1, rt, rd); |
|
4895 |
break; |
|
4896 |
case OPC_BC1: |
|
4897 |
gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2); |
|
4898 |
return; |
|
4899 |
case OPC_S_FMT: |
|
4900 |
case OPC_D_FMT: |
|
4901 |
case OPC_W_FMT: |
|
4902 |
case OPC_L_FMT: |
|
4903 |
gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); |
|
4904 |
break; |
|
4905 |
default: |
|
4906 |
generate_exception_err(ctx, EXCP_RI, 1); |
|
4907 |
break; |
|
4882 |
gen_cp1(ctx, op1, rt, rd); |
|
4883 |
break; |
|
4884 |
case OPC_BC1: |
|
4885 |
gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2); |
|
4886 |
return; |
|
4887 |
case OPC_S_FMT: |
|
4888 |
case OPC_D_FMT: |
|
4889 |
case OPC_W_FMT: |
|
4890 |
case OPC_L_FMT: |
|
4891 |
gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); |
|
4892 |
break; |
|
4893 |
default: |
|
4894 |
generate_exception_err(ctx, EXCP_RI, 1); |
|
4895 |
break; |
|
4896 |
} |
|
4897 |
} else { |
|
4898 |
generate_exception_err(ctx, EXCP_CpU, 1); |
|
4908 | 4899 |
} |
4909 |
#else |
|
4910 |
generate_exception_err(ctx, EXCP_CpU, 1); |
|
4911 |
#endif |
|
4912 | 4900 |
break; |
4913 | 4901 |
|
4914 | 4902 |
/* COP2. */ |
... | ... | |
4921 | 4909 |
generate_exception_err(ctx, EXCP_CpU, 2); |
4922 | 4910 |
break; |
4923 | 4911 |
|
4924 |
#ifdef MIPS_USES_FPU |
|
4925 | 4912 |
case OPC_CP3: |
4926 |
gen_op_cp1_enabled(); |
|
4927 |
op1 = MASK_CP3(ctx->opcode); |
|
4928 |
switch (op1) { |
|
4929 |
/* Not implemented */ |
|
4930 |
default: |
|
4931 |
generate_exception_err(ctx, EXCP_RI, 1); |
|
4932 |
break; |
|
4913 |
if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
|
4914 |
gen_op_cp1_enabled(); |
|
4915 |
op1 = MASK_CP3(ctx->opcode); |
|
4916 |
switch (op1) { |
|
4917 |
/* Not implemented */ |
|
4918 |
default: |
|
4919 |
generate_exception_err(ctx, EXCP_RI, 1); |
|
4920 |
break; |
|
4921 |
} |
|
4922 |
} else { |
|
4923 |
generate_exception(ctx, EXCP_RI); |
|
4933 | 4924 |
} |
4934 | 4925 |
break; |
4935 |
#endif |
|
4936 | 4926 |
|
4937 | 4927 |
#ifdef MIPS_HAS_MIPS64 |
4938 | 4928 |
/* MIPS64 opcodes */ |
... | ... | |
5079 | 5069 |
gen_opc_instr_start[lj] = 1; |
5080 | 5070 |
} |
5081 | 5071 |
ctx.opcode = ldl_code(ctx.pc); |
5082 |
decode_opc(&ctx); |
|
5072 |
decode_opc(env, &ctx);
|
|
5083 | 5073 |
ctx.pc += 4; |
5084 | 5074 |
|
5085 | 5075 |
if (env->singlestep_enabled) |
... | ... | |
5148 | 5138 |
return gen_intermediate_code_internal(env, tb, 1); |
5149 | 5139 |
} |
5150 | 5140 |
|
5151 |
#ifdef MIPS_USES_FPU |
|
5152 |
|
|
5153 | 5141 |
void fpu_dump_state(CPUState *env, FILE *f, |
5154 | 5142 |
int (*fpu_fprintf)(FILE *f, const char *fmt, ...), |
5155 | 5143 |
int flags) |
... | ... | |
5184 | 5172 |
} |
5185 | 5173 |
} |
5186 | 5174 |
|
5187 |
#endif /* MIPS_USES_FPU */ |
|
5188 |
|
|
5189 | 5175 |
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) |
5190 | 5176 |
/* Debug help: The architecture requires 32bit code to maintain proper |
5191 | 5177 |
sign-extened values on 64bit machines. */ |
... | ... | |
5248 | 5234 |
c0_status, env->CP0_Cause, env->CP0_EPC); |
5249 | 5235 |
cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n", |
5250 | 5236 |
env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr); |
5251 |
#ifdef MIPS_USES_FPU |
|
5252 | 5237 |
if (c0_status & (1 << CP0St_CU1)) |
5253 | 5238 |
fpu_dump_state(env, f, cpu_fprintf, flags); |
5254 |
#endif |
|
5255 | 5239 |
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS) |
5256 | 5240 |
cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags); |
5257 | 5241 |
#endif |
... | ... | |
5295 | 5279 |
env->CP0_EBase = 0x80000000; |
5296 | 5280 |
env->CP0_Config0 = MIPS_CONFIG0; |
5297 | 5281 |
env->CP0_Config1 = MIPS_CONFIG1; |
5282 |
#ifdef MIPS_USES_FPU |
|
5283 |
/* basic FPU register support */ |
|
5284 |
env->CP0_Config1 |= (1 << CP0C1_FP); |
|
5285 |
#endif |
|
5298 | 5286 |
env->CP0_Config2 = MIPS_CONFIG2; |
5299 | 5287 |
env->CP0_Config3 = MIPS_CONFIG3; |
5300 | 5288 |
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
... | ... | |
5309 | 5297 |
env->hflags |= MIPS_HFLAG_UM; |
5310 | 5298 |
env->user_mode_only = 1; |
5311 | 5299 |
#endif |
5312 |
#ifdef MIPS_USES_FPU |
|
5313 |
env->fcr0 = MIPS_FCR0; |
|
5314 |
#endif |
|
5300 |
env->fcr0 = MIPS_FCR0; |
|
5315 | 5301 |
/* XXX some guesswork here, values are CPU specific */ |
5316 | 5302 |
env->SYNCI_Step = 16; |
5317 | 5303 |
env->CCRes = 2; |
Also available in: Unified diff