📄 translate.c
字号:
} else { gen_op_load_gpr_T0(rA(ctx->opcode)); if (simm != 0) gen_op_addi(simm); } op_ldstm(lmw, rD(ctx->opcode));}/* stmw */GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ int simm = SIMM(ctx->opcode); if (rA(ctx->opcode) == 0) { gen_op_set_T0(simm); } else { gen_op_load_gpr_T0(rA(ctx->opcode)); if (simm != 0) gen_op_addi(simm); } op_ldstm(stmw, rS(ctx->opcode));}/*** Integer load and store strings ***/#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)#if defined(CONFIG_USER_ONLY)static GenOpFunc1 *gen_op_lswi[] = { &gen_op_lswi_raw, &gen_op_lswi_le_raw,};static GenOpFunc3 *gen_op_lswx[] = { &gen_op_lswx_raw, &gen_op_lswx_le_raw,};static GenOpFunc1 *gen_op_stsw[] = { &gen_op_stsw_raw, &gen_op_stsw_le_raw,};#elsestatic GenOpFunc1 *gen_op_lswi[] = { &gen_op_lswi_user, &gen_op_lswi_le_user, &gen_op_lswi_kernel, &gen_op_lswi_le_kernel,};static GenOpFunc3 *gen_op_lswx[] = { &gen_op_lswx_user, &gen_op_lswx_le_user, &gen_op_lswx_kernel, &gen_op_lswx_le_kernel,};static GenOpFunc1 *gen_op_stsw[] = { &gen_op_stsw_user, &gen_op_stsw_le_user, &gen_op_stsw_kernel, &gen_op_stsw_le_kernel,};#endif/* lswi *//* PowerPC32 specification says we must generate an exception if * rA is in the range of registers to be loaded. * In an other hand, IBM says this is valid, but rA won't be loaded. * For now, I'll follow the spec... */GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER){ int nb = NB(ctx->opcode); int start = rD(ctx->opcode); int ra = rA(ctx->opcode); int nr; if (nb == 0) nb = 32; nr = nb / 4; if (((start + nr) > 32 && start <= ra && (start + nr - 32) > ra) || ((start + nr) <= 32 && start <= ra && (start + nr) > ra)) { RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); return; } if (ra == 0) { gen_op_set_T0(0); } else { gen_op_load_gpr_T0(ra); } gen_op_set_T1(nb); /* NIP cannot be restored if the memory exception comes from an helper */ gen_op_update_nip((ctx)->nip - 4); op_ldsts(lswi, start);}/* lswx */GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER){ int ra = rA(ctx->opcode); int rb = rB(ctx->opcode); if (ra == 0) { gen_op_load_gpr_T0(rb); ra = rb; } else { gen_op_load_gpr_T0(ra); gen_op_load_gpr_T1(rb); gen_op_add(); } gen_op_load_xer_bc(); /* NIP cannot be restored if the memory exception comes from an helper */ gen_op_update_nip((ctx)->nip - 4); op_ldstsx(lswx, rD(ctx->opcode), ra, rb);}/* stswi */GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER){ int nb = NB(ctx->opcode); if (rA(ctx->opcode) == 0) { gen_op_set_T0(0); } else { gen_op_load_gpr_T0(rA(ctx->opcode)); } if (nb == 0) nb = 32; gen_op_set_T1(nb); /* NIP cannot be restored if the memory exception comes from an helper */ gen_op_update_nip((ctx)->nip - 4); op_ldsts(stsw, rS(ctx->opcode));}/* stswx */GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER){ int ra = rA(ctx->opcode); if (ra == 0) { gen_op_load_gpr_T0(rB(ctx->opcode)); ra = rB(ctx->opcode); } else { gen_op_load_gpr_T0(ra); gen_op_load_gpr_T1(rB(ctx->opcode)); gen_op_add(); } gen_op_load_xer_bc(); /* NIP cannot be restored if the memory exception comes from an helper */ gen_op_update_nip((ctx)->nip - 4); op_ldsts(stsw, rS(ctx->opcode));}/*** Memory synchronisation ***//* eieio */GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM){}/* isync */GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM){}#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()#if defined(CONFIG_USER_ONLY)static GenOpFunc *gen_op_lwarx[] = { &gen_op_lwarx_raw, &gen_op_lwarx_le_raw,};static GenOpFunc *gen_op_stwcx[] = { &gen_op_stwcx_raw, &gen_op_stwcx_le_raw,};#elsestatic GenOpFunc *gen_op_lwarx[] = { &gen_op_lwarx_user, &gen_op_lwarx_le_user, &gen_op_lwarx_kernel, &gen_op_lwarx_le_kernel,};static GenOpFunc *gen_op_stwcx[] = { &gen_op_stwcx_user, &gen_op_stwcx_le_user, &gen_op_stwcx_kernel, &gen_op_stwcx_le_kernel,};#endif/* lwarx */GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_RES){ if (rA(ctx->opcode) == 0) { gen_op_load_gpr_T0(rB(ctx->opcode)); } else { gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_load_gpr_T1(rB(ctx->opcode)); gen_op_add(); } op_lwarx(); gen_op_store_T1_gpr(rD(ctx->opcode));}/* stwcx. */GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES){ if (rA(ctx->opcode) == 0) { gen_op_load_gpr_T0(rB(ctx->opcode)); } else { gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_load_gpr_T1(rB(ctx->opcode)); gen_op_add(); } gen_op_load_gpr_T1(rS(ctx->opcode)); op_stwcx();}/* sync */GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM){}/*** Floating-point load ***/#define GEN_LDF(width, opc) \GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \{ \ uint32_t simm = SIMM(ctx->opcode); \ if (!ctx->fpu_enabled) { \ RET_EXCP(ctx, EXCP_NO_FP, 0); \ return; \ } \ if (rA(ctx->opcode) == 0) { \ gen_op_set_T0(simm); \ } else { \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ if (simm != 0) \ gen_op_addi(simm); \ } \ op_ldst(l##width); \ gen_op_store_FT1_fpr(rD(ctx->opcode)); \}#define GEN_LDUF(width, opc) \GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \{ \ uint32_t simm = SIMM(ctx->opcode); \ if (!ctx->fpu_enabled) { \ RET_EXCP(ctx, EXCP_NO_FP, 0); \ return; \ } \ if (rA(ctx->opcode) == 0 || \ rA(ctx->opcode) == rD(ctx->opcode)) { \ RET_INVAL(ctx); \ return; \ } \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ if (simm != 0) \ gen_op_addi(simm); \ op_ldst(l##width); \ gen_op_store_FT1_fpr(rD(ctx->opcode)); \ gen_op_store_T0_gpr(rA(ctx->opcode)); \}#define GEN_LDUXF(width, opc) \GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \{ \ if (!ctx->fpu_enabled) { \ RET_EXCP(ctx, EXCP_NO_FP, 0); \ return; \ } \ if (rA(ctx->opcode) == 0 || \ rA(ctx->opcode) == rD(ctx->opcode)) { \ RET_INVAL(ctx); \ return; \ } \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_add(); \ op_ldst(l##width); \ gen_op_store_FT1_fpr(rD(ctx->opcode)); \ gen_op_store_T0_gpr(rA(ctx->opcode)); \}#define GEN_LDXF(width, opc2, opc3) \GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \{ \ if (!ctx->fpu_enabled) { \ RET_EXCP(ctx, EXCP_NO_FP, 0); \ return; \ } \ if (rA(ctx->opcode) == 0) { \ gen_op_load_gpr_T0(rB(ctx->opcode)); \ } else { \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_add(); \ } \ op_ldst(l##width); \ gen_op_store_FT1_fpr(rD(ctx->opcode)); \}#define GEN_LDFS(width, op) \OP_LD_TABLE(width); \GEN_LDF(width, op | 0x20); \GEN_LDUF(width, op | 0x21); \GEN_LDUXF(width, op | 0x01); \GEN_LDXF(width, 0x17, op | 0x00)/* lfd lfdu lfdux lfdx */GEN_LDFS(fd, 0x12);/* lfs lfsu lfsux lfsx */GEN_LDFS(fs, 0x10);/*** Floating-point store ***/#define GEN_STF(width, opc) \GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \{ \ uint32_t simm = SIMM(ctx->opcode); \ if (!ctx->fpu_enabled) { \ RET_EXCP(ctx, EXCP_NO_FP, 0); \ return; \ } \ if (rA(ctx->opcode) == 0) { \ gen_op_set_T0(simm); \ } else { \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ if (simm != 0) \ gen_op_addi(simm); \ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -