📄 translate.c
字号:
.type = _typ, \ .handler = &gen_##name, \ }, \ .oname = stringify(name), \}#define GEN_OPCODE_MARK(name) \OPCODES_SECTION opcode_t opc_##name = { \ .opc1 = 0xFF, \ .opc2 = 0xFF, \ .opc3 = 0xFF, \ .pad = { 0, }, \ .handler = { \ .inval = 0x00000000, \ .type = 0x00, \ .handler = NULL, \ }, \ .oname = stringify(name), \}/* Start opcode list */GEN_OPCODE_MARK(start);/* Invalid instruction */GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE){ RET_INVAL(ctx);}static opc_handler_t invalid_handler = { .inval = 0xFFFFFFFF, .type = PPC_NONE, .handler = gen_invalid,};/*** Integer arithmetic ***/#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval) \GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_##name(); \ if (Rc(ctx->opcode) != 0) \ gen_op_set_Rc0(); \ gen_op_store_T0_gpr(rD(ctx->opcode)); \}#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval) \GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_##name(); \ if (Rc(ctx->opcode) != 0) \ gen_op_set_Rc0(); \ gen_op_store_T0_gpr(rD(ctx->opcode)); \}#define __GEN_INT_ARITH1(name, opc1, opc2, opc3) \GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_##name(); \ if (Rc(ctx->opcode) != 0) \ gen_op_set_Rc0(); \ gen_op_store_T0_gpr(rD(ctx->opcode)); \}#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3) \GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_##name(); \ if (Rc(ctx->opcode) != 0) \ gen_op_set_Rc0(); \ gen_op_store_T0_gpr(rD(ctx->opcode)); \}/* Two operands arithmetic functions */#define GEN_INT_ARITH2(name, opc1, opc2, opc3) \__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000) \__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)/* Two operands arithmetic functions with no overflow allowed */#define GEN_INT_ARITHN(name, opc1, opc2, opc3) \__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)/* One operand arithmetic functions */#define GEN_INT_ARITH1(name, opc1, opc2, opc3) \__GEN_INT_ARITH1(name, opc1, opc2, opc3) \__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)/* add add. addo addo. */GEN_INT_ARITH2 (add, 0x1F, 0x0A, 0x08);/* addc addc. addco addco. */GEN_INT_ARITH2 (addc, 0x1F, 0x0A, 0x00);/* adde adde. addeo addeo. */GEN_INT_ARITH2 (adde, 0x1F, 0x0A, 0x04);/* addme addme. addmeo addmeo. */GEN_INT_ARITH1 (addme, 0x1F, 0x0A, 0x07);/* addze addze. addzeo addzeo. */GEN_INT_ARITH1 (addze, 0x1F, 0x0A, 0x06);/* divw divw. divwo divwo. */GEN_INT_ARITH2 (divw, 0x1F, 0x0B, 0x0F);/* divwu divwu. divwuo divwuo. */GEN_INT_ARITH2 (divwu, 0x1F, 0x0B, 0x0E);/* mulhw mulhw. */GEN_INT_ARITHN (mulhw, 0x1F, 0x0B, 0x02);/* mulhwu mulhwu. */GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);/* mullw mullw. mullwo mullwo. */GEN_INT_ARITH2 (mullw, 0x1F, 0x0B, 0x07);/* neg neg. nego nego. */GEN_INT_ARITH1 (neg, 0x1F, 0x08, 0x03);/* subf subf. subfo subfo. */GEN_INT_ARITH2 (subf, 0x1F, 0x08, 0x01);/* subfc subfc. subfco subfco. */GEN_INT_ARITH2 (subfc, 0x1F, 0x08, 0x00);/* subfe subfe. subfeo subfeo. */GEN_INT_ARITH2 (subfe, 0x1F, 0x08, 0x04);/* subfme subfme. subfmeo subfmeo. */GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);/* subfze subfze. subfzeo subfzeo. */GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);/* addi */GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ int32_t simm = SIMM(ctx->opcode); if (rA(ctx->opcode) == 0) { gen_op_set_T0(simm); } else { gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_addi(simm); } gen_op_store_T0_gpr(rD(ctx->opcode));}/* addic */GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_addic(SIMM(ctx->opcode)); gen_op_store_T0_gpr(rD(ctx->opcode));}/* addic. */GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_addic(SIMM(ctx->opcode)); gen_op_set_Rc0(); gen_op_store_T0_gpr(rD(ctx->opcode));}/* addis */GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ int32_t simm = SIMM(ctx->opcode); if (rA(ctx->opcode) == 0) { gen_op_set_T0(simm << 16); } else { gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_addi(simm << 16); } gen_op_store_T0_gpr(rD(ctx->opcode));}/* mulli */GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_mulli(SIMM(ctx->opcode)); gen_op_store_T0_gpr(rD(ctx->opcode));}/* subfic */GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_subfic(SIMM(ctx->opcode)); gen_op_store_T0_gpr(rD(ctx->opcode));}/*** Integer comparison ***/#define GEN_CMP(name, opc) \GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER) \{ \ gen_op_load_gpr_T0(rA(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_##name(); \ gen_op_store_T0_crf(crfD(ctx->opcode)); \}/* cmp */GEN_CMP(cmp, 0x00);/* cmpi */GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER){ gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_cmpi(SIMM(ctx->opcode)); gen_op_store_T0_crf(crfD(ctx->opcode));}/* cmpl */GEN_CMP(cmpl, 0x01);/* cmpli */GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER){ gen_op_load_gpr_T0(rA(ctx->opcode)); gen_op_cmpli(UIMM(ctx->opcode)); gen_op_store_T0_crf(crfD(ctx->opcode));}/*** Integer logical ***/#define __GEN_LOGICAL2(name, opc2, opc3) \GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER) \{ \ gen_op_load_gpr_T0(rS(ctx->opcode)); \ gen_op_load_gpr_T1(rB(ctx->opcode)); \ gen_op_##name(); \ if (Rc(ctx->opcode) != 0) \ gen_op_set_Rc0(); \ gen_op_store_T0_gpr(rA(ctx->opcode)); \}#define GEN_LOGICAL2(name, opc) \__GEN_LOGICAL2(name, 0x1C, opc)#define GEN_LOGICAL1(name, opc) \GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER) \{ \ gen_op_load_gpr_T0(rS(ctx->opcode)); \ gen_op_##name(); \ if (Rc(ctx->opcode) != 0) \ gen_op_set_Rc0(); \ gen_op_store_T0_gpr(rA(ctx->opcode)); \}/* and & and. */GEN_LOGICAL2(and, 0x00);/* andc & andc. */GEN_LOGICAL2(andc, 0x01);/* andi. */GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rS(ctx->opcode)); gen_op_andi_(UIMM(ctx->opcode)); gen_op_set_Rc0(); gen_op_store_T0_gpr(rA(ctx->opcode));}/* andis. */GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rS(ctx->opcode)); gen_op_andi_(UIMM(ctx->opcode) << 16); gen_op_set_Rc0(); gen_op_store_T0_gpr(rA(ctx->opcode));}/* cntlzw */GEN_LOGICAL1(cntlzw, 0x00);/* eqv & eqv. */GEN_LOGICAL2(eqv, 0x08);/* extsb & extsb. */GEN_LOGICAL1(extsb, 0x1D);/* extsh & extsh. */GEN_LOGICAL1(extsh, 0x1C);/* nand & nand. */GEN_LOGICAL2(nand, 0x0E);/* nor & nor. */GEN_LOGICAL2(nor, 0x03);/* or & or. */GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rS(ctx->opcode)); /* Optimisation for mr case */ if (rS(ctx->opcode) != rB(ctx->opcode)) { gen_op_load_gpr_T1(rB(ctx->opcode)); gen_op_or(); } if (Rc(ctx->opcode) != 0) gen_op_set_Rc0(); gen_op_store_T0_gpr(rA(ctx->opcode));}/* orc & orc. */GEN_LOGICAL2(orc, 0x0C);/* xor & xor. */GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER){ gen_op_load_gpr_T0(rS(ctx->opcode)); /* Optimisation for "set to zero" case */ if (rS(ctx->opcode) != rB(ctx->opcode)) { gen_op_load_gpr_T1(rB(ctx->opcode)); gen_op_xor(); } else { gen_op_set_T0(0); } if (Rc(ctx->opcode) != 0) gen_op_set_Rc0(); gen_op_store_T0_gpr(rA(ctx->opcode));}/* ori */GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ uint32_t uimm = UIMM(ctx->opcode); if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) { /* NOP */ return; } gen_op_load_gpr_T0(rS(ctx->opcode)); if (uimm != 0) gen_op_ori(uimm); gen_op_store_T0_gpr(rA(ctx->opcode));}/* oris */GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ uint32_t uimm = UIMM(ctx->opcode); if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) { /* NOP */ return; } gen_op_load_gpr_T0(rS(ctx->opcode)); if (uimm != 0) gen_op_ori(uimm << 16); gen_op_store_T0_gpr(rA(ctx->opcode));}/* xori */GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER){ uint32_t uimm = UIMM(ctx->opcode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -