diff --git a/rebuild_wrappers.py b/rebuild_wrappers.py index e01dbe58a..0518ffda9 100755 --- a/rebuild_wrappers.py +++ b/rebuild_wrappers.py @@ -849,17 +849,17 @@ def main(root: str, files: Iterable[Filename], ver: str): allowed_conv = conventions[allowed_conv_ident] # H could be allowed maybe? - allowed_simply: Dict[str, str] = {"ARM64": "v", "RV64": "v", "LA64": "v"} - allowed_regs : Dict[str, str] = {"ARM64": "cCwWiuIUlLp", "RV64": "CWIUlLp", "LA64": "CWIUlLp"} - allowed_fpr : Dict[str, str] = {"ARM64": "fd", "RV64": "fd", "LA64": "fd"} - allowed_sextw : Dict[str, str] = {"ARM64": "", "RV64": "cwiu", "LA64": "cwiu"} + allowed_simply: Dict[str, str] = {"ARM64": "v", "RV64": "v", "LA64": "v", "PPC64LE": "v"} + allowed_regs : Dict[str, str] = {"ARM64": "cCwWiuIUlLp", "RV64": "CWIUlLp", "LA64": "CWIUlLp", "PPC64LE": "CWIUlLp"} + allowed_fpr : Dict[str, str] = {"ARM64": "fd", "RV64": "fd", "LA64": "fd", "PPC64LE": "fd"} + allowed_sextw : Dict[str, str] = {"ARM64": "", "RV64": "cwiu", "LA64": "cwiu", "PPC64LE": "cwiu"} # Detect functions which return in an x87 register retx87_wraps: Dict[ClausesStr, List[FunctionType]] = {} return_x87: str = "D" # Sanity checks - forbidden_simple: Dict[str, str] = {"ARM64": "EDVOSNHPAxXYb", "RV64": "EDVOSNHPAxXYb", "LA64": "EDVOSNHPAxXYb"} + forbidden_simple: Dict[str, str] = {"ARM64": "EDVOSNHPAxXYb", "RV64": "EDVOSNHPAxXYb", "LA64": "EDVOSNHPAxXYb", "PPC64LE": "EDVOSNHPAxXYb"} assert(all(k in allowed_simply for k in forbidden_simple)) assert(all(k in allowed_regs for k in forbidden_simple)) assert(all(k in allowed_fpr for k in forbidden_simple)) diff --git a/src/dynarec/ppc64le/dynarec_ppc64le_00.c b/src/dynarec/ppc64le/dynarec_ppc64le_00.c index a0b2a8abe..5dd68a9f0 100644 --- a/src/dynarec/ppc64le/dynarec_ppc64le_00.c +++ b/src/dynarec/ppc64le/dynarec_ppc64le_00.c @@ -579,7 +579,6 @@ uintptr_t dynarec64_00(dynarec_ppc64le_t* dyn, uintptr_t addr, uintptr_t ip, int BF_INSERT(xFlags, x3, F_SF, F_SF); } IFX (X_PF) emit_pf(dyn, ninst, gd, x3, x4); - IFX (X_ALL) SPILL_EFLAGS(); break; case 0x6A: INST_NAME("PUSH Ib"); @@ -635,7 +634,6 @@ uintptr_t dynarec64_00(dynarec_ppc64le_t* dyn, uintptr_t addr, uintptr_t ip, int BF_INSERT(xFlags, x3, F_SF, F_SF); } IFX (X_PF) emit_pf(dyn, ninst, gd, x3, x4); - IFX (X_ALL) SPILL_EFLAGS(); break; #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F, I) \ READFLAGS_FUSION(F, x1, x2, x3, x4, x5); \ @@ -1002,7 +1000,7 @@ uintptr_t dynarec64_00(dynarec_ppc64le_t* dyn, uintptr_t addr, uintptr_t ip, int MVxw(TO_NAT((nextop & 7) + (rex.b << 3)), gd); } else { // mem <= reg addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, DS_DISP, 0); - if(!lock && BOX64ENV(unity) && !VolatileRangesContains(ip) && ((fixedaddress==0x80) || (fixedaddress==0x84) || (fixedaddress==0xc0) || (fixedaddress==0xc4))) { + if (!lock && BOX64ENV(unity) && !VolatileRangesContains(ip) && ((fixedaddress == 0x80) || (fixedaddress == 0x84) || (fixedaddress == 0xc0) || (fixedaddress == 0xc4))) { DMB_ISH(); lock = 1; } @@ -1053,7 +1051,7 @@ uintptr_t dynarec64_00(dynarec_ppc64le_t* dyn, uintptr_t addr, uintptr_t ip, int MVxw(gd, TO_NAT((nextop & 7) + (rex.b << 3))); } else { addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, DS_DISP, 0); - if(!lock && BOX64ENV(unity) && !VolatileRangesContains(ip) && ((fixedaddress==0x80) || (fixedaddress==0x84) || (fixedaddress==0xc0) || (fixedaddress==0xc4))) { + if (!lock && BOX64ENV(unity) && !VolatileRangesContains(ip) && ((fixedaddress == 0x80) || (fixedaddress == 0x84) || (fixedaddress == 0xc0) || (fixedaddress == 0xc4))) { lock = 1; } SMREADLOCK(lock); @@ -1565,7 +1563,6 @@ uintptr_t dynarec64_00(dynarec_ppc64le_t* dyn, uintptr_t addr, uintptr_t ip, int ADDI(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip CALL_S(const_int3, -1, x1); SMWRITE2(); - LOAD_XEMU_CALL(); MOV64x(x3, dyn->insts[ninst].natcall); ADDI(x3, x3, 2 + 8 + 8); BNE_MARK(xRIP, x3); // Not the expected address, exit dynarec block @@ -2060,6 +2057,1221 @@ uintptr_t dynarec64_00(dynarec_ppc64le_t* dyn, uintptr_t addr, uintptr_t ip, int DEFAULT; } break; + case 0x9C: + INST_NAME("PUSHF"); + READFLAGS(X_ALL); + PUSH1z(xFlags); + break; + case 0x9D: + INST_NAME("POPF"); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + POP1z(xFlags); + MOV32w(x1, 0x3E7FD7); + AND(xFlags, xFlags, x1); + ORI(xFlags, xFlags, 0x202); + SET_DFNONE(); + if (box64_wine) { // should this be done all the time? + ANDI(x1, xFlags, 1 << F_TF); + CBZ_NEXT(x1); + // go to epilog, TF should trigger at end of next opcode, so using Interpreter only + LWZ(x4, offsetof(x64emu_t, flags), xEmu); + ORI(x4, x4, 1 << FLAGS_NO_TF); + STW(x4, offsetof(x64emu_t, flags), xEmu); + jump_to_epilog(dyn, addr, 0, ninst); + } + break; + case 0x9E: + INST_NAME("SAHF"); + SETFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF, SF_SUBSET, NAT_FLAGS_NOFUSION); + LI(x1, ~0b11010101); + AND(xFlags, xFlags, x1); + NOT(x1, x1); + SRDI(x2, xRAX, 8); + AND(x1, x1, x2); + OR(xFlags, xFlags, x1); + SET_DFNONE(); + break; + case 0x9F: + INST_NAME("LAHF"); + READFLAGS(X_CF | X_PF | X_AF | X_ZF | X_SF); + BF_INSERT(xRAX, xFlags, 15, 8); + break; + case 0xA4: + SMREAD(); + if (rex.rep) { + INST_NAME("REP MOVSB"); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1 << F_DF); + BNEZ_MARK2(x1); + IF_UNALIGNED (ip) { + // unaligned path: byte-by-byte only to avoid SIGBUS on CI memory + B_MARK_nocond; + } else { + // special optim for large RCX value on forward case only + if (BOX64DRENV(dynarec_safeflags)) { + SUB(x2, xRDI, xRSI); + LI(x6, 8); + BLT_MARK(x2, x6); + } + OR(x1, xRSI, xRDI); + ANDI(x1, x1, 7); + BNEZ_MARK(x1); + LI(x6, 8); + MARK3; + BLT_MARK(xRCX, x6); + LD(x1, 0, xRSI); + STD(x1, 0, xRDI); + ADDI(xRSI, xRSI, 8); + ADDI(xRDI, xRDI, 8); + ADDI(xRCX, xRCX, -8); + BNEZ_MARK3(xRCX); + B_NEXT_nocond; + } + MARK; // Part with DF==0 + LBZ(x1, 0, xRSI); + STB(x1, 0, xRDI); + ADDI(xRSI, xRSI, 1); + ADDI(xRDI, xRDI, 1); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + B_NEXT_nocond; + MARK2; // Part with DF==1 + LBZ(x1, 0, xRSI); + STB(x1, 0, xRDI); + ADDI(xRSI, xRSI, -1); + ADDI(xRDI, xRDI, -1); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK2(xRCX); + // done + } else { + INST_NAME("MOVSB"); + GETDIR(x3, x1, 1); + LBZ(x1, 0, xRSI); + STB(x1, 0, xRDI); + ADD(xRSI, xRSI, x3); + ADD(xRDI, xRDI, x3); + } + SMWRITE(); + break; + case 0xA5: + SMREAD(); + if (rex.rep) { + INST_NAME("REP MOVSD"); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1 << F_DF); + BNEZ_MARK2(x1); + MARK; // Part with DF==0 + LDxw(x1, xRSI, 0); + SDxw(x1, xRDI, 0); + ADDI(xRSI, xRSI, rex.w ? 8 : 4); + ADDI(xRDI, xRDI, rex.w ? 8 : 4); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + B_NEXT_nocond; + MARK2; // Part with DF==1 + LDxw(x1, xRSI, 0); + SDxw(x1, xRDI, 0); + ADDI(xRSI, xRSI, rex.w ? -8 : -4); + ADDI(xRDI, xRDI, rex.w ? -8 : -4); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK2(xRCX); + // done + } else { + INST_NAME("MOVSD"); + GETDIR(x3, x1, rex.w ? 8 : 4); + LDxw(x1, xRSI, 0); + SDxw(x1, xRDI, 0); + ADD(xRSI, xRSI, x3); + ADD(xRDI, xRDI, x3); + } + SMWRITE(); + break; + case 0xA6: + switch (rex.rep) { + case 1: + case 2: + if (rex.rep == 1) { + INST_NAME("REPNZ CMPSB"); + } else { + INST_NAME("REPZ CMPSB"); + } + if (BOX64DRENV(dynarec_safeflags) > 1) { + READFLAGS(X_ALL); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + } else + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + SMREAD(); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1 << F_DF); + BNEZ_MARK2(x1); + MARK; // Part with DF==0 + LBZ(x1, 0, xRSI); + LBZ(x2, 0, xRDI); + ADDI(xRSI, xRSI, 1); + ADDI(xRDI, xRDI, 1); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNEZ_MARK(xRCX); + B_MARK3_nocond; + MARK2; // Part with DF==1 + LBZ(x1, 0, xRSI); + LBZ(x2, 0, xRDI); + ADDI(xRSI, xRSI, -1); + ADDI(xRDI, xRDI, -1); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNEZ_MARK2(xRCX); + MARK3; // end + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + default: + INST_NAME("CMPSB"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + GETDIR(x3, x1, 1); + SMREAD(); + LBZ(x1, 0, xRSI); + LBZ(x2, 0, xRDI); + ADD(xRSI, xRSI, x3); + ADD(xRDI, xRDI, x3); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + } + break; + case 0xA7: + switch (rex.rep) { + case 1: + case 2: + if (rex.rep == 1) { + INST_NAME("REPNZ CMPSD"); + } else { + INST_NAME("REPZ CMPSD"); + } + if (BOX64DRENV(dynarec_safeflags) > 1) { + READFLAGS(X_ALL); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + } else + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + SMREAD(); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1 << F_DF); + BNEZ_MARK2(x1); + MARK; // Part with DF==0 + LDxw(x1, xRSI, 0); + LDxw(x2, xRDI, 0); + ADDI(xRSI, xRSI, rex.w ? 8 : 4); + ADDI(xRDI, xRDI, rex.w ? 8 : 4); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNEZ_MARK(xRCX); + B_MARK3_nocond; + MARK2; // Part with DF==1 + LDxw(x1, xRSI, 0); + LDxw(x2, xRDI, 0); + ADDI(xRSI, xRSI, rex.w ? -8 : -4); + ADDI(xRDI, xRDI, rex.w ? -8 : -4); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNEZ_MARK2(xRCX); + MARK3; // end + emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6); + break; + default: + INST_NAME("CMPSD"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + GETDIR(x3, x1, rex.w ? 8 : 4); + SMREAD(); + LDxw(x1, xRSI, 0); + LDxw(x2, xRDI, 0); + ADD(xRSI, xRSI, x3); + ADD(xRDI, xRDI, x3); + emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6); + break; + } + break; + case 0xAA: + if (rex.rep) { + INST_NAME("REP STOSB"); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1 << F_DF); + BNEZ_MARK2(x1); + IF_UNALIGNED (ip) { + // unaligned path: byte-by-byte only to avoid SIGBUS on CI memory + B_MARK_nocond; + } else { + // special optim for large RCX value on forward case only + ANDI(x1, xRDI, 7); + BNEZ_MARK(x1); + // broadcast low byte of RAX to 8 bytes in x3 + ANDI(x3, xRAX, 0xFF); + SLDI(x1, x3, 8); + OR(x3, x3, x1); + SLDI(x1, x3, 16); + OR(x3, x3, x1); + SLDI(x1, x3, 32); + OR(x3, x3, x1); + LI(x6, 8); + MARK3; + BLT_MARK(xRCX, x6); + STD(x3, 0, xRDI); + ADDI(xRDI, xRDI, 8); + ADDI(xRCX, xRCX, -8); + BNEZ_MARK3(xRCX); + B_NEXT_nocond; + } + MARK; // Part with DF==0 + STB(xRAX, 0, xRDI); + ADDI(xRDI, xRDI, 1); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + B_NEXT_nocond; + MARK2; // Part with DF==1 + STB(xRAX, 0, xRDI); + ADDI(xRDI, xRDI, -1); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK2(xRCX); + // done + } else { + INST_NAME("STOSB"); + GETDIR(x3, x1, 1); + STB(xRAX, 0, xRDI); + ADD(xRDI, xRDI, x3); + } + SMWRITE(); + break; + case 0xAB: + if (rex.rep) { + INST_NAME("REP STOSD"); + CBZ_NEXT(xRCX); + ANDI(x1, xFlags, 1 << F_DF); + BNEZ_MARK2(x1); + MARK; // Part with DF==0 + SDxw(xRAX, xRDI, 0); + ADDI(xRDI, xRDI, rex.w ? 8 : 4); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + B_NEXT_nocond; + MARK2; // Part with DF==1 + SDxw(xRAX, xRDI, 0); + ADDI(xRDI, xRDI, rex.w ? -8 : -4); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK2(xRCX); + // done + } else { + INST_NAME("STOSD"); + GETDIR(x3, x1, rex.w ? 8 : 4); + SDxw(xRAX, xRDI, 0); + ADD(xRDI, xRDI, x3); + } + SMWRITE(); + break; + case 0xAC: + if (rex.rep) { + INST_NAME("REP LODSB"); + GETDIR(x1, x2, 1); + SMREAD(); + CBZ_NEXT(xRCX); + MARK; + LBZ(x2, 0, xRSI); + ADD(xRSI, xRSI, x1); + BF_INSERT(xRAX, x2, 7, 0); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + } else { + INST_NAME("LODSB"); + GETDIR(x1, x2, 1); + SMREAD(); + LBZ(x2, 0, xRSI); + ADD(xRSI, xRSI, x1); + BF_INSERT(xRAX, x2, 7, 0); + } + break; + case 0xAD: + if (rex.rep) { + INST_NAME("REP LODSD"); + CBZ_NEXT(xRCX); + GETDIR(x1, x2, rex.w ? 8 : 4); + MARK; + LDxw(xRAX, xRSI, 0); + ADD(xRSI, xRSI, x1); + ADDI(xRCX, xRCX, -1); + BNEZ_MARK(xRCX); + } else { + INST_NAME("LODSD"); + GETDIR(x1, x2, rex.w ? 8 : 4); + LDxw(xRAX, xRSI, 0); + ADD(xRSI, xRSI, x1); + } + break; + case 0xAE: + switch (rex.rep) { + case 1: + case 2: + if (rex.rep == 1) { + INST_NAME("REPNZ SCASB"); + } else { + INST_NAME("REPZ SCASB"); + } + if (BOX64DRENV(dynarec_safeflags) > 1) { + READFLAGS(X_ALL); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + } else + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + SMREAD(); + CBZ_NEXT(xRCX); + ANDI(x1, xRAX, 0xff); + ANDI(x2, xFlags, 1 << F_DF); + BNEZ_MARK2(x2); + MARK; // Part with DF==0 + LBZ(x2, 0, xRDI); + ADDI(xRDI, xRDI, 1); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNE_MARK(xRCX, xZR); + B_MARK3_nocond; + MARK2; // Part with DF==1 + LBZ(x2, 0, xRDI); + ADDI(xRDI, xRDI, -1); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNE_MARK2(xRCX, xZR); + MARK3; // end + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + default: + INST_NAME("SCASB"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + GETDIR(x3, x1, 1); + ANDI(x1, xRAX, 0xff); + LBZ(x2, 0, xRDI); + ADD(xRDI, xRDI, x3); + emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6); + break; + } + break; + case 0xAF: + switch (rex.rep) { + case 1: + case 2: + if (rex.rep == 1) { + INST_NAME("REPNZ SCASD"); + } else { + INST_NAME("REPZ SCASD"); + } + if (BOX64DRENV(dynarec_safeflags) > 1) { + READFLAGS(X_ALL); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + } else + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + SMREAD(); + CBZ_NEXT(xRCX); + if (rex.w) { + MR(x1, xRAX); + } else { + ZEROUP2(x1, xRAX); + } + ANDI(x2, xFlags, 1 << F_DF); + BNEZ_MARK2(x2); + MARK; // Part with DF==0 + LDxw(x2, xRDI, 0); + ADDI(xRDI, xRDI, rex.w ? 8 : 4); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNE_MARK(xRCX, xZR); + B_MARK3_nocond; + MARK2; // Part with DF==1 + LDxw(x2, xRDI, 0); + ADDI(xRDI, xRDI, rex.w ? -8 : -4); + ADDI(xRCX, xRCX, -1); + if (rex.rep == 1) { + BEQ_MARK3(x1, x2); + } else { + BNE_MARK3(x1, x2); + } + BNE_MARK2(xRCX, xZR); + MARK3; // end + emit_cmp32(dyn, ninst, rex, x1, x2, x3, x4, x5, x6); + break; + default: + INST_NAME("SCASD"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_NOFUSION); + GETDIR(x3, x1, rex.w ? 8 : 4); + LDxw(x2, xRDI, 0); + ADD(xRDI, xRDI, x3); + emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6); + break; + } + break; + case 0xCC: + SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); + SKIPTEST(x1); + if (IsBridgeSignature(PK(0), PK(1))) { + addr += 2; + BARRIER(BARRIER_FLOAT); + INST_NAME("Special Box64 instruction"); + if (PK64(0) == 0) { + addr += 8; + MESSAGE(LOG_DEBUG, "Exit x64 Emu\n"); + MOV64x(x1, 1); + STW(x1, offsetof(x64emu_t, quit), xEmu); + *ok = 0; + *need_epilog = 1; + } else { + MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip), 1)); + x87_stackcount(dyn, ninst, x1); + x87_forget(dyn, ninst, x3, x4, 0); + sse_purge07cache(dyn, ninst, x3); + // Partially support isSimpleWrapper + tmp = isSimpleWrapper(*(wrapper_t*)(addr)); + if (isRetX87Wrapper(*(wrapper_t*)(addr))) + // return value will be on the stack, so the stack depth needs to be updated + x87_purgecache(dyn, ninst, 0, x3, x1, x4); + if (tmp < 0 || (tmp & 15) > 1) + tmp = 0; // TODO: removed when FP is in place + if ((BOX64ENV(log) < 2 && !BOX64ENV(rolling_log)) && tmp) { + call_n(dyn, ninst, (void*)(addr + 8), tmp); + SMWRITE2(); + addr += 8 + 8; + } else { + GETIP(ip + 1, x7); // read the 0xCC + STORE_XEMU_CALL(); + ADDI(x3, xRIP, 8 + 8 + 2); // expected return address + ADDI(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip + CALL_(const_int3, -1, x3, x1, 0); + SMWRITE2(); + addr += 8 + 8; + BNE_MARK(xRIP, x3); + LWZ(x1, offsetof(x64emu_t, quit), xEmu); + CBZ_NEXT(x1); + MARK; + LOAD_XEMU_REM(); + jump_to_epilog_fast(dyn, 0, xRIP, ninst); + } + } + } else { + INST_NAME("INT 3"); + if (!BOX64ENV(ignoreint3)) { + // check if TRAP signal is handled + TABLE64C(x1, const_context); + MOV32w(x2, offsetof(box64context_t, signals[X64_SIGTRAP])); + LDX(x3, x1, x2); + BEQZ_MARK(x3); + GETIP(addr, x7); + STORE_XEMU_CALL(); + CALL(const_native_int3, -1, 0, 0); + MARK; + jump_to_epilog(dyn, addr, 0, ninst); + *need_epilog = 0; + *ok = 0; + } + } + break; + case 0xCD: + u8 = F8; + NOTEST(x1); + if (box64_wine && (u8 == 0x2D || u8 == 0x2C || u8 == 0x29)) { + INST_NAME("INT 29/2c/2d"); + // lets do nothing + MESSAGE(LOG_INFO, "INT 29/2c/2d Windows interruption\n"); + GETIP(ip, x7); // priviledged instruction, IP not updated + STORE_XEMU_CALL(); + MOV32w(x1, u8); + CALL(const_native_int, -1, x1, 0); + } else if (u8 == 0x80) { + INST_NAME("32bits SYSCALL"); + NOTEST(x1); + SMEND(); + GETIP(addr, x7); + STORE_XEMU_CALL(); + CALL_S(const_x86syscall, -1, 0); + TABLE64(x3, addr); // expected return address + BNE_MARK(xRIP, x3); + LWZ(x1, offsetof(x64emu_t, quit), xEmu); + CBZ_NEXT(x1); + MARK; + LOAD_XEMU_REM(); + jump_to_epilog(dyn, 0, xRIP, ninst); + } else if (u8 == 0x03) { + INST_NAME("INT 3"); + if (BOX64DRENV(dynarec_safeflags) > 1) { + READFLAGS(X_PEND); + } else { + SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state + } + GETIP(addr, x7); + STORE_XEMU_CALL(); + CALL(const_native_int3, -1, 0, 0); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + } else { + INST_NAME("INT n"); + if (BOX64DRENV(dynarec_safeflags) > 1) { + READFLAGS(X_PEND); + } else { + SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state + } + if (rex.is32bits && u8 == 0x04) { + GETIP(addr, x7); + } else { + GETIP(ip, x7); // priviledged instruction, IP not updated + } + STORE_XEMU_CALL(); + MOV32w(x1, u8); + CALL(const_native_int, -1, x1, 0); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + } + break; + case 0xCE: + if (!rex.is32bits) { + DEFAULT; + } else { + INST_NAME("INTO"); + READFLAGS(X_OF); + GETIP(addr, x7); + ANDI(x1, xFlags, 1 << F_OF); + BEQZ_MARK(x1); + STORE_XEMU_CALL(); + MOV32w(x1, 4); + CALL_S(const_native_int, -1, x1); + MARK; + } + break; + case 0xF5: + INST_NAME("CMC"); + READFLAGS(X_CF); + SETFLAGS(X_CF, SF_SUBSET, NAT_FLAGS_NOFUSION); + XORI(xFlags, xFlags, 1 << F_CF); + break; + case 0xF6: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 0: + case 1: + INST_NAME("TEST Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); + if (MODREG && (rex.rex || (((nextop & 7) >> 2) == 0))) { + // quick path for low 8bit registers + if (rex.rex) + ed = TO_NAT((nextop & 7) + (rex.b << 3)); + else + ed = TO_NAT(nextop & 3); + } else { + GETEB(x1, 1); + ed = x1; + } + u8 = F8; + emit_test8c(dyn, ninst, ed, u8, x3, x4, x5); + break; + case 2: + INST_NAME("NOT Eb"); + GETEB(x1, 0); + NOT(x1, x1); + EBBACK(); + break; + case 3: + INST_NAME("NEG Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); + GETEB(x1, 0); + emit_neg8(dyn, ninst, x1, x2, x4); + EBBACK(); + break; + case 4: + INST_NAME("MUL AL, Eb"); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + GETEB(x1, 0); + ANDI(x2, xRAX, 0xff); + MULLW(x1, x2, x1); + BF_INSERT(xRAX, x1, 15, 0); + SET_DFNONE(); + CLEAR_FLAGS(x3); + IFX (X_CF | X_OF) { + SRDI(x3, x1, 8); + SNEZ(x3, x3); + IFX (X_CF) BF_INSERT(xFlags, x3, F_CF, F_CF); + IFX (X_OF) BF_INSERT(xFlags, x3, F_OF, F_OF); + } + IFX (X_SF) { + SRDI(x3, xRAX, 7); + BF_INSERT(xFlags, x3, F_SF, F_SF); + } + IFX (X_PF) emit_pf(dyn, ninst, xRAX, x3, x4); + break; + case 5: + INST_NAME("IMUL AL, Eb"); + SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); + GETSEB(x1, 0); + EXTSB(x2, xRAX); + MULLW(x1, x2, x1); + BF_INSERT(xRAX, x1, 15, 0); + SET_DFNONE(); + CLEAR_FLAGS(x3); + IFX (X_CF | X_OF) { + EXTSH(x1, xRAX); + EXTSB(x2, x1); + XOR(x3, x1, x2); + SNEZ(x3, x3); + IFX (X_CF) BF_INSERT(xFlags, x3, F_CF, F_CF); + IFX (X_OF) BF_INSERT(xFlags, x3, F_OF, F_OF); + } + IFX (X_SF) { + SRDI(x3, xRAX, 7); + BF_INSERT(xFlags, x3, F_SF, F_SF); + } + IFX (X_PF) emit_pf(dyn, ninst, xRAX, x3, x4); + break; + case 6: + INST_NAME("DIV Eb"); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + GETEB(x1, 0); + BF_EXTRACT(x2, xRAX, 15, 0); + if (BOX64ENV(dynarec_div0)) { + BNE_MARK3(x1, xZR); + GETIP_(ip, x7); + STORE_XEMU_CALL(); + CALL(const_native_div0, -1, 0, 0); + CLEARIP(); + jump_to_epilog(dyn, 0, xRIP, ninst); + MARK3; + } + DIVWU(x3, x2, ed); + // Remainder = dividend - quotient * divisor + MULLW(x4, x3, ed); + SUB(x4, x2, x4); + BF_INSERT(xRAX, x3, 7, 0); + BF_INSERT(xRAX, x4, 15, 8); + FORCE_DFNONE(); + IFX (X_ZF | X_PF) LI(x6, 1); + IFX (X_OF) BF_INSERT(xFlags, xZR, F_OF, F_OF); + IFX (X_CF) BF_INSERT(xFlags, xZR, F_CF, F_CF); + IFX (X_AF) BF_INSERT(xFlags, xZR, F_AF, F_AF); + IFX (X_ZF) BF_INSERT(xFlags, x6, F_ZF, F_ZF); + IFX (X_SF) BF_INSERT(xFlags, xZR, F_SF, F_SF); + IFX (X_PF) BF_INSERT(xFlags, x6, F_PF, F_PF); + break; + case 7: + INST_NAME("IDIV Eb"); + SKIPTEST(x1); + if (BOX64DRENV(dynarec_safeflags)) { + SETFLAGS(X_SF | X_PF | X_ZF | X_AF, SF_SUBSET, NAT_FLAGS_NOFUSION); + } else if (BOX64ENV(cputype)) { + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + } + GETSEB(x1, 0); + if (BOX64ENV(dynarec_div0)) { + BNE_MARK3(x1, xZR); + GETIP_(ip, x7); + STORE_XEMU_CALL(); + CALL(const_native_div0, -1, 0, 0); + CLEARIP(); + jump_to_epilog(dyn, 0, xRIP, ninst); + MARK3; + } + EXTSH(x2, xRAX); + DIVW(x3, x2, ed); + // Remainder = dividend - quotient * divisor + MULLW(x4, x3, ed); + SUB(x4, x2, x4); + BF_INSERT(xRAX, x3, 7, 0); + BF_INSERT(xRAX, x4, 15, 8); + FORCE_DFNONE(); + break; + default: + DEFAULT; + } + break; + case 0xF7: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 0: + case 1: + INST_NAME("TEST Ed, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); + GETED(4); + i64 = F32S; + emit_test32c(dyn, ninst, rex, ed, i64, x3, x4, x5); + break; + case 2: + INST_NAME("NOT Ed"); + GETED(0); + NOT(ed, ed); + if (!rex.w && MODREG) + ZEROUP(ed); + WBACK; + break; + case 3: + INST_NAME("NEG Ed"); + SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); + GETED(0); + emit_neg32(dyn, ninst, rex, ed, x3, x4); + WBACK; + break; + case 4: + INST_NAME("MUL EAX, Ed"); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + GETED(0); + if (rex.w) { + if (ed == xRDX) + gd = x3; + else + gd = xRDX; + MULHDU(gd, xRAX, ed); + MULLD(xRAX, xRAX, ed); + if (gd != xRDX) { MR(xRDX, gd); } + } else { + ZEROUP2(x3, xRAX); + if (MODREG) { + ZEROUP2(x4, ed); + ed = x4; + } + MULLD(xRDX, x3, ed); // 64 <- 32x32 + ZEROUP2(xRAX, xRDX); + SRDI(xRDX, xRDX, 32); + } + SET_DFNONE(); + CLEAR_FLAGS(x3); + IFX (X_CF | X_OF) { + SNEZ(x3, xRDX); + IFX (X_CF) BF_INSERT(xFlags, x3, F_CF, F_CF); + IFX (X_OF) BF_INSERT(xFlags, x3, F_OF, F_OF); + } + IFX (X_SF) { + SRDI(x3, xRAX, rex.w ? 63 : 31); + BF_INSERT(xFlags, x3, F_SF, F_SF); + } + IFX (X_PF) emit_pf(dyn, ninst, xRAX, x3, x5); + break; + case 5: + INST_NAME("IMUL EAX, Ed"); + SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); + GETSED(0); + if (rex.w) { + if (ed == xRDX) + gd = x3; + else + gd = xRDX; + MULHD(gd, xRAX, ed); + MULLD(xRAX, xRAX, ed); + if (gd != xRDX) { MR(xRDX, gd); } + } else { + EXTSW(x3, xRAX); // sign extend 32bits-> 64bits + MULLD(xRDX, x3, ed); // 64 <- 32x32 + ZEROUP2(xRAX, xRDX); + SRDI(xRDX, xRDX, 32); + } + SET_DFNONE(); + CLEAR_FLAGS(x3); + IFX (X_CF | X_OF | X_SF) { + SRAIxw(x5, xRAX, rex.w ? 63 : 31); + MVxw(x6, xRDX); + XOR(x3, x6, x5); + SNEZ(x3, x3); + IFX (X_CF) BF_INSERT(xFlags, x3, F_CF, F_CF); + IFX (X_OF) BF_INSERT(xFlags, x3, F_OF, F_OF); + IFX (X_SF) BF_INSERT(xFlags, x5, F_SF, F_SF); + } + IFX (X_PF) emit_pf(dyn, ninst, xRAX, x3, x5); + break; + case 6: + INST_NAME("DIV Ed"); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + FORCE_DFNONE(); + if (!rex.w) { + GETED(0); + if (ninst && (nextop == 0xF0) + && dyn->insts[ninst - 1].x64.addr + && *(uint8_t*)(dyn->insts[ninst - 1].x64.addr) == 0xB8 + && *(uint32_t*)(dyn->insts[ninst - 1].x64.addr + 1) == 0) { + // hack for some protection that check a divide by zero actually trigger a divide by zero exception + MESSAGE(LOG_INFO, "Divide by 0 hack\n"); + GETIP(ip, x7); + STORE_XEMU_CALL(); + CALL(const_native_div0, -1, 0, 0); + } else { + if (BOX64ENV(dynarec_div0)) { + BNE_MARK3(ed, xZR); + GETIP_(ip, x7); + STORE_XEMU_CALL(); + CALL(const_native_div0, -1, 0, 0); + CLEARIP(); + jump_to_epilog(dyn, 0, xRIP, ninst); + MARK3; + } + SLDI(x3, xRDX, 32); + ZEROUP2(x2, xRAX); + OR(x3, x3, x2); + if (MODREG) { + ZEROUP2(x4, ed); + ed = x4; + } + DIVDU(x2, x3, ed); + // Remainder = dividend - quotient * divisor + MULLD(xRDX, x2, ed); + SUB(xRDX, x3, xRDX); + ZEROUP2(xRAX, x2); + ZEROUP(xRDX); + } + } else { + if (ninst + && dyn->insts[ninst - 1].x64.addr + && *(uint8_t*)(dyn->insts[ninst - 1].x64.addr) == 0x31 + && *(uint8_t*)(dyn->insts[ninst - 1].x64.addr + 1) == 0xD2) { + GETED(0); + if (BOX64ENV(dynarec_div0)) { + BNE_MARK3(ed, xZR); + GETIP_(ip, x7); + STORE_XEMU_CALL(); + CALL(const_native_div0, -1, 0, 0); + CLEARIP(); + jump_to_epilog(dyn, 0, xRIP, ninst); + MARK3; + } + DIVDU(x2, xRAX, ed); + // Remainder = dividend - quotient * divisor + MULLD(xRDX, x2, ed); + SUB(xRDX, xRAX, xRDX); + MR(xRAX, x2); + } else { + GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op... + if (BOX64ENV(dynarec_div0)) { + BNE_MARK3(ed, xZR); + GETIP_(ip, x7); + STORE_XEMU_CALL(); + CALL(const_native_div0, -1, 0, 0); + CLEARIP(); + jump_to_epilog(dyn, 0, xRIP, ninst); + MARK3; + } + BEQ_MARK(xRDX, xZR); + CALL(const_div64, -1, ed, 0); + B_NEXT_nocond; + MARK; + DIVDU(x2, xRAX, ed); + // Remainder = dividend - quotient * divisor + MULLD(xRDX, x2, ed); + SUB(xRDX, xRAX, xRDX); + MR(xRAX, x2); + } + } + CLEAR_FLAGS(x7); + IFX (X_ZF) ORI(xFlags, xFlags, 1 << F_ZF); + IFX (X_PF) ORI(xFlags, xFlags, 1 << F_PF); + break; + case 7: + INST_NAME("IDIV Ed"); + SKIPTEST(x1); + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + // TODO: handle zero divisor + if (!rex.w) { + SET_DFNONE(); + GETSED(0); + SLDI(x3, xRDX, 32); + ZEROUP2(x2, xRAX); + OR(x3, x3, x2); + // x3 = RDX:RAX combined 64-bit dividend (sign-extended 32-bit) + DIVD(x2, x3, ed); + // Remainder = dividend - quotient * divisor + MULLD(xRDX, x2, ed); + SUB(xRDX, x3, xRDX); + ZEROUP2(xRAX, x2); + ZEROUP(xRDX); + } else { + if (ninst && dyn->insts + && dyn->insts[ninst - 1].x64.addr + && *(uint8_t*)(dyn->insts[ninst - 1].x64.addr) == 0x48 + && *(uint8_t*)(dyn->insts[ninst - 1].x64.addr + 1) == 0x99) { + FORCE_DFNONE(); + GETED(0); + DIVD(x2, xRAX, ed); + // Remainder = dividend - quotient * divisor + MULLD(xRDX, x2, ed); + SUB(xRDX, xRAX, xRDX); + MR(xRAX, x2); + } else { + GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op... + // need to see if RDX == 0 and RAX not signed + // or RDX == -1 and RAX signed + BNE_MARK2(xRDX, xZR); + BGE_MARK(xRAX, xZR); + MARK2; + NOT(x2, xRDX); + BNE_MARK3(x2, xZR); + BLT_MARK(xRAX, xZR); + MARK3; + CALL(const_idiv64, -1, ed, 0); + B_NEXT_nocond; + MARK; + DIVD(x2, xRAX, ed); + // Remainder = dividend - quotient * divisor + MULLD(xRDX, x2, ed); + SUB(xRDX, xRAX, xRDX); + MR(xRAX, x2); + FORCE_DFNONE(); + } + } + break; + default: + DEFAULT; + } + break; + case 0xF8: + INST_NAME("CLC"); + SETFLAGS(X_CF, SF_SUBSET, NAT_FLAGS_NOFUSION); + SET_DFNONE(); + BF_INSERT(xFlags, xZR, F_CF, F_CF); + break; + case 0xF9: + INST_NAME("STC"); + SETFLAGS(X_CF, SF_SUBSET, NAT_FLAGS_NOFUSION); + SET_DFNONE(); + ORI(xFlags, xFlags, 1 << F_CF); + break; + case 0xFA: + case 0xFB: + INST_NAME(opcode == 0xFA ? "CLI" : "STI"); + if (rex.is32bits && BOX64ENV(ignoreint3)) { + } else { + if (BOX64DRENV(dynarec_safeflags) > 1) { + READFLAGS(X_PEND); + } else { + SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state + } + GETIP(ip, x7); // privileged instruction, IP not updated + STORE_XEMU_CALL(); + CALL(const_native_priv, -1, 0, 0); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + } + break; + case 0xFC: + INST_NAME("CLD"); + BF_INSERT(xFlags, xZR, F_DF, F_DF); + break; + case 0xFD: + INST_NAME("STD"); + ORI(xFlags, xFlags, 1 << F_DF); + break; + case 0xFE: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 0: + INST_NAME("INC Eb"); + SETFLAGS(X_ALL & ~X_CF, SF_SUBSET, NAT_FLAGS_FUSION); + GETEB(x1, 0); + emit_inc8(dyn, ninst, ed, x2, x4, x5); + EBBACK(); + break; + case 1: + INST_NAME("DEC Eb"); + SETFLAGS(X_ALL & ~X_CF, SF_SUBSET, NAT_FLAGS_FUSION); + GETEB(x1, 0); + emit_dec8(dyn, ninst, ed, x2, x4, x5); + EBBACK(); + break; + default: + DEFAULT; + } + break; + case 0xFF: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 0: // INC Ed + INST_NAME("INC Ed"); + SETFLAGS(X_ALL & ~X_CF, SF_SUBSET, NAT_FLAGS_FUSION); + GETED(0); + emit_inc32(dyn, ninst, rex, ed, x3, x4, x5, x6); + WBACK; + break; + case 1: // DEC Ed + INST_NAME("DEC Ed"); + SETFLAGS(X_ALL & ~X_CF, SF_SUBSET, NAT_FLAGS_FUSION); + GETED(0); + emit_dec32(dyn, ninst, rex, ed, x3, x4, x5, x6); + WBACK; + break; + case 2: + INST_NAME("CALL Ed"); + PASS2IF ((BOX64DRENV(dynarec_safeflags) > 1) || ((ninst && dyn->insts[ninst - 1].x64.set_flags) || ((ninst > 1) && dyn->insts[ninst - 2].x64.set_flags)), 1) { + READFLAGS(X_PEND); // that's suspicious + } else { + SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to put flag in "don't care" state + } + GETEDz(0); + if (BOX64DRENV(dynarec_callret) && BOX64DRENV(dynarec_bigblock) > 1) { + BARRIER(BARRIER_FULL); + } else { + BARRIER(BARRIER_FLOAT); + *need_epilog = 0; + *ok = 0; + } + GETIP_(addr, x7); + if (BOX64DRENV(dynarec_callret)) { + SET_HASCALLRET(); + // Push shadow return address {native_addr, x86_addr} + if (addr < (dyn->start + dyn->isize)) { + // return address is within this block + j64 = (dyn->insts) ? (dyn->insts[ninst].epilog - (dyn->native_size)) : 0; + BCL(20, 31, 4); + MFLR(x4); + ADDI(x4, x4, j64 - 4); + MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64 >> 2); + } else { + // return address is outside this block — point to MARK + j64 = (dyn->insts) ? (GETMARK - (dyn->native_size)) : 0; + BCL(20, 31, 4); + MFLR(x4); + ADDI(x4, x4, j64 - 4); + MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64 >> 2); + } + ADDI(xSP, xSP, -16); + STD(x4, 0, xSP); // native return addr + STD(xRIP, 8, xSP); // x86 return addr + } + PUSH1z(xRIP); + jump_to_next(dyn, 0, ed, ninst, rex.is32bits); + if (BOX64DRENV(dynarec_callret) && addr >= (dyn->start + dyn->isize)) { + // return address is outside this block — emit landing pad + MARK; + j64 = getJumpTableAddress64(addr); + if (dyn->need_reloc) AddRelocTable64RetEndBlock(dyn, ninst, addr, STEP); + TABLE64_(x4, j64); + LD(x4, 0, x4); + MTCTR(x4); + BCTR(); + } + break; + case 3: // CALL FAR Ed + if (MODREG) { + DEFAULT; + } else { + INST_NAME("CALL FAR Ed"); + READFLAGS(X_PEND); + BARRIER(BARRIER_FLOAT); + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, NO_DISP, 0); + LDxw(x1, wback, 0); + ed = x1; + LHZ(x3, rex.w ? 8 : 4, wback); + LHZ(x5, offsetof(x64emu_t, segs[_CS]), xEmu); + if (BOX64DRENV(dynarec_callret) && BOX64DRENV(dynarec_bigblock) > 1) { + BARRIER(BARRIER_FULL); + } else { + BARRIER(BARRIER_FLOAT); + *need_epilog = 0; + *ok = 0; + } + GETIP_(addr, x7); + if (BOX64DRENV(dynarec_callret)) { + SET_HASCALLRET(); + // Push shadow return address {native_addr, x86_addr} + // Note: CS is not tested on return, but should be ok + if (addr < (dyn->start + dyn->isize)) { + j64 = (dyn->insts) ? (dyn->insts[ninst].epilog - (dyn->native_size)) : 0; + BCL(20, 31, 4); + MFLR(x4); + ADDI(x4, x4, j64 - 4); + MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64 >> 2); + } else { + j64 = (dyn->insts) ? (GETMARK - (dyn->native_size)) : 0; + BCL(20, 31, 4); + MFLR(x4); + ADDI(x4, x4, j64 - 4); + MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64 >> 2); + } + ADDI(xSP, xSP, -16); + STD(x4, 0, xSP); // native return addr + STD(xRIP, 8, xSP); // x86 return addr + } + if (rex.w) { + PUSH1(x5); + PUSH1(xRIP); + } else { + PUSH1_32(x5); + PUSH1_32(xRIP); + } + STH(x3, offsetof(x64emu_t, segs[_CS]), xEmu); + jump_to_next(dyn, 0, ed, ninst, rex.is32bits); + if (BOX64DRENV(dynarec_callret) && addr >= (dyn->start + dyn->isize)) { + // return address is outside this block — emit landing pad + MARK; + j64 = getJumpTableAddress64(addr); + if (dyn->need_reloc) AddRelocTable64RetEndBlock(dyn, ninst, addr, STEP); + TABLE64_(x4, j64); + LD(x4, 0, x4); + MTCTR(x4); + BCTR(); + } + CLEARIP(); + } + break; + case 4: // JMP Ed + INST_NAME("JMP Ed"); + READFLAGS(X_PEND); + BARRIER(BARRIER_FLOAT); + GETEDz(0); + jump_to_next(dyn, 0, ed, ninst, rex.is32bits); + *need_epilog = 0; + *ok = 0; + break; + case 5: // JMP FAR Ed + if (MODREG) { + DEFAULT; + } else { + INST_NAME("JMP FAR Ed"); + READFLAGS(X_PEND); + BARRIER(BARRIER_FLOAT); + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, NO_DISP, 0); + LDxw(x1, wback, 0); + ed = x1; + LHZ(x3, rex.w ? 8 : 4, wback); + STH(x3, offsetof(x64emu_t, segs[_CS]), xEmu); + jump_to_next(dyn, 0, ed, ninst, rex.w ? 0 : 1); + *need_epilog = 0; + *ok = 0; + } + break; + case 6: // Push Ed + INST_NAME("PUSH Ed"); + GETEDz(0); + PUSH1z(ed); + SMWRITE(); + break; + + default: + DEFAULT; + } + break; default: DEFAULT; } diff --git a/src/dynarec/ppc64le/dynarec_ppc64le_emit_math.c b/src/dynarec/ppc64le/dynarec_ppc64le_emit_math.c index 938202ebe..a0d8fd991 100644 --- a/src/dynarec/ppc64le/dynarec_ppc64le_emit_math.c +++ b/src/dynarec/ppc64le/dynarec_ppc64le_emit_math.c @@ -20,7 +20,7 @@ #include "dynarec_ppc64le_functions.h" #include "../dynarec_helper.h" -// emit ADD32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch +// emit ADD32 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch void emit_add32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) { IFX (X_PEND) { @@ -84,10 +84,8 @@ void emit_add32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, in } } IFX (X_SF) { - SRDI(s3, s1, rex.w ? 63 : 31); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); } if (!rex.w) { ZEROUP(s1); @@ -103,7 +101,7 @@ void emit_add32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, in if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); } -// emit ADD32 instruction, from s1, constant c, store result in s1 using s3 and s4 as scratch +// emit ADD32 instruction, from s1, constant c, store result in s1 using s2, s3, s4 and s5 as scratch void emit_add32c(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s2, int s3, int s4, int s5) { if ((s1 == xRSP) && (BOX64DRENV(dynarec_safeflags) < 2) && (!dyn->insts || (dyn->insts[ninst].x64.gen_flags == X_PEND) || (!BOX64ENV(dynarec_df) && (dyn->insts[ninst].x64.gen_flags == X_ALL)))) { @@ -187,10 +185,8 @@ void emit_add32c(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int64_t c } } IFX (X_SF) { - SRDI(s3, s1, rex.w ? 63 : 31); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); } if (!rex.w) { ZEROUP(s1); @@ -258,10 +254,8 @@ void emit_add8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4 ORI(xFlags, xFlags, 1 << F_ZF); } IFX (X_SF) { - SRDI(s3, s1, 7); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, 7, 7); + BF_INSERT(xFlags, s3, F_SF, F_SF); } IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -269,7 +263,7 @@ void emit_add8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4 if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); } -// emit ADD8 instruction, from s1, const c, store result in s1 using s3 and s4 as scratch +// emit ADD8 instruction, from s1, const c, store result in s1 using s2, s3 and s4 as scratch void emit_add8c(dynarec_ppc64le_t* dyn, int ninst, int s1, int32_t c, int s2, int s3, int s4) { IFX (X_PEND) { @@ -326,10 +320,73 @@ void emit_add8c(dynarec_ppc64le_t* dyn, int ninst, int s1, int32_t c, int s2, in ORI(xFlags, xFlags, 1 << F_ZF); } IFX (X_SF) { - SRDI(s3, s1, 7); + BF_EXTRACT(s3, s1, 7, 7); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit ADD16 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch +void emit_add16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) +{ + IFX (X_PEND) { + STH(s1, offsetof(x64emu_t, op1), xEmu); + STH(s2, offsetof(x64emu_t, op2), xEmu); + SET_DF(s3, d_add16); + } else IFXORNAT (X_ALL) { + SET_DFNONE(); + } + IFX (X_AF | X_OF) { + OR(s3, s1, s2); // s3 = op1 | op2 + AND(s4, s1, s2); // s4 = op1 & op2 + } + + ADD(s1, s1, s2); + + // d_add16 will use 32bits result to check for CF + IFX (X_PEND) { + STW(s1, offsetof(x64emu_t, res), xEmu); + } + + CLEAR_FLAGS(s5); + IFX (X_AF | X_OF) { + ANDC(s3, s3, s1); // s3 = ~res & (op1 | op2) + OR(s3, s3, s4); // cc = (~res & (op1 | op2)) | (op1 & op2) + IFX (X_AF) { + ANDId(s4, s3, 0x08); // AF: cc & 0x08 + CMPDI(s4, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + SRDI(s3, s3, 14); + SRDI(s4, s3, 1); + XOR(s3, s3, s4); + ANDId(s3, s3, 1); // OF: xor of two MSB's of cc + BF_INSERT(xFlags, s3, F_OF, F_OF); + } + } + + IFX (X_CF) { + SRDI(s3, s1, 16); CMPDI(s3, 0); BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + ORI(xFlags, xFlags, 1 << F_CF); + } + + BF_EXTRACT(s1, s1, 15, 0); + + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, 15, 15); + BF_INSERT(xFlags, s3, F_SF, F_SF); } IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -357,10 +414,8 @@ void emit_sub8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4 SUB(s1, s1, s2); ANDId(s1, s1, 0xff); IFX (X_SF) { - SRDI(s3, s1, 7); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, 7, 7); + BF_INSERT(xFlags, s3, F_SF, F_SF); } IFX (X_PEND) { STB(s1, offsetof(x64emu_t, res), xEmu); @@ -384,6 +439,46 @@ void emit_sub8c(dynarec_ppc64le_t* dyn, int ninst, int s1, int32_t c, int s2, in emit_sub8(dyn, ninst, s1, s2, s3, s4, s5); } +// emit SUB16 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch +void emit_sub16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) +{ + IFX (X_PEND) { + STH(s1, offsetof(x64emu_t, op1), xEmu); + STH(s2, offsetof(x64emu_t, op2), xEmu); + SET_DF(s3, d_sub16); + } else IFXORNAT (X_ALL) { + SET_DFNONE(); + } + + IFX (X_AF | X_CF | X_OF) { + // for later flag calculation + NOT(s5, s1); + } + + SUB(s1, s1, s2); + IFX (X_PEND) { + STH(s1, offsetof(x64emu_t, res), xEmu); + } + + CLEAR_FLAGS(s3); + IFX (X_SF) { + BF_EXTRACT(s3, s1, 15, 15); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + BF_EXTRACT(s1, s1, 15, 0); + + CALC_SUB_FLAGS(s5, s2, s1, s3, s4, 16); + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + // emit SUB32 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch void emit_sub32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) { @@ -406,10 +501,8 @@ void emit_sub32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, in SDxw(s1, xEmu, offsetof(x64emu_t, res)); } IFX (X_SF) { - SRDI(s3, s1, rex.w ? 63 : 31); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); } if (!rex.w) { ZEROUP(s1); @@ -470,10 +563,8 @@ void emit_sub32c(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int64_t c SDxw(s1, xEmu, offsetof(x64emu_t, res)); } IFX (X_SF) { - SRDI(s3, s1, rex.w ? 63 : 31); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); } if (!rex.w) { ZEROUP(s1); @@ -509,20 +600,17 @@ void emit_sbb8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4 SUB(s1, s1, s2); ANDId(s3, xFlags, 1 << F_CF); SUB(s1, s1, s3); + ANDId(s1, s1, 0xff); CLEAR_FLAGS(s3); IFX (X_PEND) { - // d_sbb8 will use 16bits result to check for CF - STH(s1, offsetof(x64emu_t, res), xEmu); + STB(s1, offsetof(x64emu_t, res), xEmu); } - ANDId(s1, s1, 0xff); CALC_SUB_FLAGS(s5, s2, s1, s3, s4, 8); IFX (X_SF) { - SRDI(s3, s1, 7); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, 7, 7); + BF_INSERT(xFlags, s3, F_SF, F_SF); } IFX (X_ZF) { CMPDI(s1, 0); @@ -563,18 +651,15 @@ void emit_sbb16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s SUB(s1, s1, s3); CLEAR_FLAGS(s3); - IFX (X_PEND) { - // d_sbb16 will use 32bits result to check for CF - STW(s1, offsetof(x64emu_t, res), xEmu); - } - // Check SF: shift left 48, check sign, shift back - SLDI(s1, s1, 48); IFX (X_SF) { - CMPDI(s1, 0); - BGE(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, 15, 15); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + BF_EXTRACT(s1, s1, 15, 0); + + IFX (X_PEND) { + STH(s1, offsetof(x64emu_t, res), xEmu); } - SRDI(s1, s1, 48); CALC_SUB_FLAGS(s5, s2, s1, s3, s4, 16); IFX (X_ZF) { @@ -610,10 +695,8 @@ void emit_sbb32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, in CLEAR_FLAGS(s3); IFX (X_SF) { - SRDI(s3, s1, rex.w ? 63 : 31); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); } if (!rex.w) ZEROUP(s1); IFX (X_PEND) { @@ -631,13 +714,201 @@ void emit_sbb32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, in if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); } -// emit ADC8 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch + +// emit NEG8 instruction, from s1, store result in s1 using s2 and s3 as scratch +void emit_neg8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3) +{ + IFX (X_PEND) { + STB(s1, offsetof(x64emu_t, op1), xEmu); + SET_DF(s3, d_neg8); + } else IFXORNAT (X_ALL) { + SET_DFNONE(); + } + IFX (X_AF | X_OF) { + MV(s3, s1); // s3 = op1 + } + + NEG(s1, s1); + ANDId(s1, s1, 0xff); + IFX (X_PEND) { + STB(s1, offsetof(x64emu_t, res), xEmu); + } + + CLEAR_FLAGS(s2); + IFX (X_CF) { + CMPDI(s1, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_CF); + } + + IFX (X_AF | X_OF) { + OR(s3, s1, s3); // s3 = res | op1 + IFX (X_AF) { + /* af = bc & 0x8 */ + ANDId(s2, s3, 8); + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + /* of = ((bc >> (width-2)) ^ (bc >> (width-1))) & 0x1; */ + SRDI(s2, s3, 6); + SRDI(s3, s2, 1); + XOR(s2, s2, s3); + ANDId(s2, s2, 1); + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, 7, 7); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit NEG32 instruction, from s1, store result in s1 using s2 and s3 as scratch +void emit_neg32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3) +{ + IFX (X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, op1)); + SET_DF(s3, rex.w ? d_neg64 : d_neg32); + } else IFXORNAT (X_ALL) { + SET_DFNONE(); + } + + IFX (X_AF | X_OF) { + MV(s3, s1); // s3 = op1 + } + + NEG(s1, s1); + if (!rex.w) ZEROUP(s1); + IFX (X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, res)); + } + + CLEAR_FLAGS(s2); + IFX (X_CF) { + CMPDI(s1, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_CF); + } + + IFX (X_AF | X_OF) { + OR(s3, s1, s3); // s3 = res | op1 + IFX (X_AF) { + /* af = bc & 0x8 */ + ANDId(s2, s3, 8); + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + /* of = ((bc >> (width-2)) ^ (bc >> (width-1))) & 0x1; */ + SRDI(s2, s3, (rex.w ? 64 : 32) - 2); + SRDI(s3, s2, 1); + XOR(s2, s2, s3); + ANDId(s2, s2, 1); + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + if (!rex.w) { + ZEROUP(s1); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit NEG16 instruction, from s1, store result in s1 using s2 and s3 as scratch +void emit_neg16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3) +{ + IFX (X_PEND) { + STH(s1, offsetof(x64emu_t, op1), xEmu); + SET_DF(s3, d_neg16); + } else IFXORNAT (X_ALL) { + SET_DFNONE(); + } + CLEAR_FLAGS(s3); + IFX (X_AF | X_OF) { + MV(s3, s1); // s3 = op1 + } + + NEG(s1, s1); + BF_EXTRACT(s1, s1, 15, 0); + IFX (X_PEND) { + STH(s1, offsetof(x64emu_t, res), xEmu); + } + + IFX (X_CF) { + CMPDI(s1, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_CF); + } + + IFX (X_AF | X_OF) { + OR(s3, s1, s3); // s3 = res | op1 + IFX (X_AF) { + /* af = bc & 0x8 */ + ANDId(s2, s3, 8); + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + /* of = ((bc >> (width-2)) ^ (bc >> (width-1))) & 0x1; */ + SRDI(s2, s3, 14); + SRDI(s3, s2, 1); + XOR(s2, s2, s3); + ANDId(s2, s2, 1); + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, 15, 15); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit ADC8 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch void emit_adc8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) { IFX (X_PEND) { STB(s1, offsetof(x64emu_t, op1), xEmu); STB(s2, offsetof(x64emu_t, op2), xEmu); - SET_DF(s3, d_adc8); + SET_DF(s3, d_adc8b); } else IFXORNAT (X_ALL) { SET_DFNONE(); } @@ -654,7 +925,7 @@ void emit_adc8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4 CLEAR_FLAGS(s3); IFX (X_PEND) { // d_adc8 will use 16bits result to check for CF - STH(s1, offsetof(x64emu_t, res), xEmu); + STB(s1, offsetof(x64emu_t, res), xEmu); } IFX (X_AF | X_OF) { ANDC(s3, s4, s1); // s3 = ~res & (op1 | op2) @@ -680,7 +951,7 @@ void emit_adc8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4 ORI(xFlags, xFlags, 1 << F_CF); } - ANDId(s1, s1, 0xff); + ANDId(s1, s1, 0xff); // unneeded? IFX (X_ZF) { CMPDI(s1, 0); @@ -688,10 +959,8 @@ void emit_adc8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4 ORI(xFlags, xFlags, 1 << F_ZF); } IFX (X_SF) { - SRDI(s3, s1, 7); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, 7, 7); + BF_INSERT(xFlags, s3, F_SF, F_SF); } IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -706,13 +975,13 @@ void emit_adc8c(dynarec_ppc64le_t* dyn, int ninst, int s1, int32_t c, int s3, in emit_adc8(dyn, ninst, s1, s5, s3, s4, s6); } -// emit ADC16 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch +// emit ADC16 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch void emit_adc16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) { IFX (X_PEND) { STH(s1, offsetof(x64emu_t, op1), xEmu); STH(s2, offsetof(x64emu_t, op2), xEmu); - SET_DF(s3, d_adc16); + SET_DF(s3, d_adc16b); } else IFXORNAT (X_ALL) { SET_DFNONE(); } @@ -729,7 +998,7 @@ void emit_adc16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s CLEAR_FLAGS(s3); IFX (X_PEND) { // d_adc16 will use 32bits result to check for CF - STW(s1, offsetof(x64emu_t, res), xEmu); + STH(s1, offsetof(x64emu_t, res), xEmu); } IFX (X_AF | X_OF) { ANDC(s3, s4, s1); // s3 = ~res & (op1 | op2) @@ -755,7 +1024,7 @@ void emit_adc16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s ORI(xFlags, xFlags, 1 << F_CF); } - BF_EXTRACT(s1, s1, 15, 0); + BF_EXTRACT(s1, s1, 15, 0); // unneeded? IFX (X_ZF) { CMPDI(s1, 0); @@ -763,10 +1032,8 @@ void emit_adc16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s ORI(xFlags, xFlags, 1 << F_ZF); } IFX (X_SF) { - SRDI(s3, s1, 15); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, 15, 15); + BF_INSERT(xFlags, s3, F_SF, F_SF); } IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -774,7 +1041,7 @@ void emit_adc16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); } -// emit ADC32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch +// emit ADC32 instruction, from s1, s2, store result in s1 using s3, s4, s5 and s6 as scratch void emit_adc32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5, int s6) { IFX (X_PEND) { @@ -844,10 +1111,8 @@ void emit_adc32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, in } } IFX (X_SF) { - SRDI(s3, s1, rex.w ? 63 : 31); - CMPDI(s3, 0); - BEQ(8); - ORI(xFlags, xFlags, 1 << F_SF); + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); } if (!rex.w) { ZEROUP(s1); @@ -862,3 +1127,308 @@ void emit_adc32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, in } if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); } + +// emit INC8 instruction, from s1, store result in s1 using s2, s3 and s4 as scratch +void emit_inc8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4) +{ + SET_DFNONE(); + IFX (X_ALL) { + // preserving CF + MOV64x(s4, (1UL << F_AF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); + ANDC(xFlags, xFlags, s4); + } + + IFX (X_AF | X_OF) { + ORI(s3, s1, 1); // s3 = op1 | op2 + ANDId(s4, s1, 1); // s4 = op1 & op2 + } + + ADDI(s1, s1, 1); + + IFX (X_AF | X_OF) { + ANDC(s3, s3, s1); // s3 = ~res & (op1 | op2) + OR(s3, s3, s4); // cc = (~res & (op1 | op2)) | (op1 & op2) + IFX (X_AF) { + ANDId(s2, s3, 0x08); // AF: cc & 0x08 + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + SRDI(s3, s3, 6); + SRDI(s2, s3, 1); + XOR(s3, s3, s2); + ANDId(s3, s3, 1); // OF: xor of two MSB's of cc + BF_INSERT(xFlags, s3, F_OF, F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s2, s1, 7, 7); + BF_INSERT(xFlags, s2, F_SF, F_SF); + } + ANDId(s1, s1, 0xff); + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit INC16 instruction, from s1, store result in s1 using s2, s3 and s4 as scratch +void emit_inc16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4) +{ + SET_DFNONE(); + IFX (X_ALL) { + // preserving CF + MOV64x(s4, (1UL << F_AF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); + ANDC(xFlags, xFlags, s4); + } + + IFX (X_AF | X_OF) { + ORI(s3, s1, 1); // s3 = op1 | op2 + ANDId(s4, s1, 1); // s4 = op1 & op2 + } + + ADDI(s1, s1, 1); + + IFX (X_AF | X_OF) { + ANDC(s3, s3, s1); // s3 = ~res & (op1 | op2) + OR(s3, s3, s4); // cc = (~res & (op1 | op2)) | (op1 & op2) + IFX (X_AF) { + ANDId(s4, s3, 0x08); // AF: cc & 0x08 + CMPDI(s4, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + SRDI(s3, s3, 14); + SRDI(s4, s3, 1); + XOR(s3, s3, s4); + ANDId(s3, s3, 1); // OF: xor of two MSB's of cc + BF_INSERT(xFlags, s3, F_OF, F_OF); + } + } + + BF_EXTRACT(s1, s1, 15, 0); + + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, 15, 15); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit INC32 instruction, from s1, store result in s1 using s2, s3, s4 and s5 as scratch +void emit_inc32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) +{ + SET_DFNONE(); + IFX (X_ALL) { + // preserving CF + MOV64x(s4, (1UL << F_AF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); + ANDC(xFlags, xFlags, s4); + } + + IFX (X_AF | X_OF) { + ORI(s3, s1, 1); // s3 = op1 | op2 + ANDId(s5, s1, 1); // s5 = op1 & op2 + } + + ADDIxw(s1, s1, 1); + + IFX (X_AF | X_OF) { + ANDC(s3, s3, s1); // s3 = ~res & (op1 | op2) + OR(s3, s3, s5); // cc = (~res & (op1 | op2)) | (op1 & op2) + IFX (X_AF) { + ANDId(s2, s3, 0x08); // AF: cc & 0x08 + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + SRDI(s3, s3, rex.w ? 62 : 30); + SRDI(s2, s3, 1); + XOR(s3, s3, s2); + ANDId(s3, s3, 1); // OF: xor of two MSB's of cc + BF_INSERT(xFlags, s3, F_OF, F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + if (!rex.w) { + ZEROUP(s1); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit DEC8 instruction, from s1, store result in s1 using s2, s3 and s4 as scratch +void emit_dec8(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4) +{ + SET_DFNONE(); + IFX (X_ALL) { + // preserving CF + MOV64x(s4, (1UL << F_AF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); + ANDC(xFlags, xFlags, s4); + } + + IFX (X_AF | X_OF) { + NOT(s4, s1); // s4 = ~op1 + ORI(s3, s4, 1); // s3 = ~op1 | op2 + ANDId(s4, s4, 1); // s4 = ~op1 & op2 + } + + ADDI(s1, s1, -1); + + IFX (X_AF | X_OF) { + AND(s3, s1, s3); // s3 = res & (~op1 | op2) + OR(s3, s3, s4); // cc = (res & (~op1 | op2)) | (~op1 & op2) + IFX (X_AF) { + ANDId(s2, s3, 0x08); // AF: cc & 0x08 + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + SRDI(s3, s3, 6); + SRDI(s2, s3, 1); + XOR(s3, s3, s2); + ANDId(s3, s3, 1); // OF: xor of two MSB's of cc + BF_INSERT(xFlags, s3, F_OF, F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s2, s1, 7, 7); + BF_INSERT(xFlags, s2, F_SF, F_SF); + } + ANDId(s1, s1, 0xff); + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit DEC16 instruction, from s1, store result in s1 using s2, s3, s4 and s5 as scratch +void emit_dec16(dynarec_ppc64le_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) +{ + SET_DFNONE(); + + IFX (X_AF | X_OF) { + NOT(s5, s1); + ORI(s3, s5, 1); // s3 = ~op1 | op2 + ANDId(s5, s5, 1); // s5 = ~op1 & op2 + } + + ADDI(s1, s1, -1); + IFX (X_ALL) { + // preserving CF + MOV64x(s4, (1UL << F_AF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); + ANDC(xFlags, xFlags, s4); + } + + IFX (X_AF | X_OF) { + AND(s3, s1, s3); // s3 = res & (~op1 | op2) + OR(s3, s3, s5); // cc = (res & (~op1 | op2)) | (~op1 & op2) + IFX (X_AF) { + ANDId(s2, s3, 0x08); // AF: cc & 0x08 + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + SRDI(s3, s3, 14); + SRDI(s2, s3, 1); + XOR(s3, s3, s2); + ANDId(s3, s3, 1); // OF: xor of two MSB's of cc + BF_INSERT(xFlags, s3, F_OF, F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, 15, 15); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} + +// emit DEC32 instruction, from s1, store result in s1 using s2, s3, s4 and s5 as scratch +void emit_dec32(dynarec_ppc64le_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) +{ + SET_DFNONE(); + + IFX (X_AF | X_OF) { + NOT(s5, s1); + ORI(s3, s5, 1); // s3 = ~op1 | op2 + ANDId(s5, s5, 1); // s5 = ~op1 & op2 + } + + ADDIxw(s1, s1, -1); + IFX (X_ALL) { + // preserving CF + MOV64x(s4, (1UL << F_AF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); + ANDC(xFlags, xFlags, s4); + } + IFX (X_AF | X_OF) { + AND(s3, s1, s3); // s3 = res & (~op1 | op2) + OR(s3, s3, s5); // cc = (res & (~op1 | op2)) | (~op1 & op2) + IFX (X_AF) { + ANDId(s2, s3, 0x08); // AF: cc & 0x08 + CMPDI(s2, 0); + BEQ(8); + ORI(xFlags, xFlags, 1 << F_AF); + } + IFX (X_OF) { + SRDI(s3, s3, rex.w ? 62 : 30); + SRDI(s2, s3, 1); + XOR(s3, s3, s2); + ANDId(s3, s3, 1); // OF: xor of two MSB's of cc + BF_INSERT(xFlags, s3, F_OF, F_OF); + } + } + IFX (X_SF) { + BF_EXTRACT(s3, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); + BF_INSERT(xFlags, s3, F_SF, F_SF); + } + if (!rex.w) ZEROUP(s1); + IFX (X_PF) { + emit_pf(dyn, ninst, s1, s3, s2); + } + IFX (X_ZF) { + CMPDI(s1, 0); + BNE(8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); +} diff --git a/src/dynarec/ppc64le/dynarec_ppc64le_helper.h b/src/dynarec/ppc64le/dynarec_ppc64le_helper.h index ce596cf6d..33df6d0a3 100644 --- a/src/dynarec/ppc64le/dynarec_ppc64le_helper.h +++ b/src/dynarec/ppc64le/dynarec_ppc64le_helper.h @@ -300,6 +300,30 @@ ed = x1; \ } +// GETEDz like GETED, but uses LDz instead of LDxw +#define GETEDz(D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, DS_DISP, D); \ + LDz(x1, wback, fixedaddress); \ + ed = x1; \ + } + +// GETEDH can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI +#define GETEDH(hint, ret, D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, DS_DISP, D); \ + ed = ret; \ + LDxw(ed, wback, fixedaddress); \ + } + // FAKEED like GETED, but doesn't get anything #define FAKEED \ @@ -366,6 +390,26 @@ wb1 = 1; \ ed = i; \ } + +// GETSED sign extend ED, will use x1 for ed and x2 for wback +#define GETSED(D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + wback = 0; \ + if (!rex.w) { \ + EXTSW(x1, ed); \ + ed = x1; \ + } \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, DS_DISP, D); \ + if (rex.w) \ + LD(x1, fixedaddress, wback); \ + else \ + LWA(x1, fixedaddress, wback); \ + ed = x1; \ + } + // GETGB will use i for gd #define GETGB(i) \ if (rex.rex) { \ @@ -860,6 +904,14 @@ #define CALLRET_LOOP() NOP() #endif +#ifndef IF_UNALIGNED +#define IF_UNALIGNED(A) if(dyn->insts[ninst].unaligned) +#endif + +#ifndef IF_ALIGNED +#define IF_ALIGNED(A) if(!dyn->insts[ninst].unaligned) +#endif + #ifndef TABLE64 #define TABLE64(A, V) #endif @@ -874,6 +926,13 @@ #define TABLE64_(A, V) #endif + +#define GETDIR(r, s, Z) \ + MOV32w(r, Z); /* mask=1<<10 */ \ + ANDId(s, xFlags, 1 << F_DF); \ + BEQ(4 + 4); \ + NEG(r, r); + #define ARCH_INIT() SMSTART() #define ARCH_RESET() diff --git a/src/dynarec/ppc64le/ppc64le_next.S b/src/dynarec/ppc64le/ppc64le_next.S index 80e352c25..0cac85db3 100644 --- a/src/dynarec/ppc64le/ppc64le_next.S +++ b/src/dynarec/ppc64le/ppc64le_next.S @@ -47,12 +47,17 @@ ppc64le_next: ld %r5, 16(%r1) // arg2 = "from" (saved LR) addi %r6, %r1, 80 // arg3 = address of saved RIP on stack - // Restore TOC for calling C code - // We need to load the TOC for LinkNext - use the saved TOC - // Note: In ELFv2, r12 must point to the function entry for local calls - // For external calls via PLT, the linker handles it + // Restore TOC (r2) before calling C code. + // JIT code calls native wrapped functions (e.g., libc) which set r2 to + // their own TOC. Since `bl LinkNext` is resolved as a local call (skipping + // LinkNext's global entry that reloads r2), we must restore it ourselves. + // emu->xSPSave (offset 808 from Emu/r31) points to the prolog's stack + // frame, which has the saved TOC at offset 24. + ld %r2, 808(Emu) // r2 = prolog's frame SP (from xSPSave) + ld %r2, 24(%r2) // r2 = saved TOC from prolog frame + bl LinkNext - nop // TOC restore slot (linker fills if needed) + nop // TOC restore slot (linker may patch) // Preserve return value (jump target) in r12 mr %r12, %r3 diff --git a/src/libtools/sigtools.c b/src/libtools/sigtools.c index 62a3a174f..c02ef4d98 100644 --- a/src/libtools/sigtools.c +++ b/src/libtools/sigtools.c @@ -110,6 +110,8 @@ if(BOX64ENV(showsegv)) printf_log(LOG_INFO, "Marked db %p as dirty, and address #include "dynarec/arm64/arm64_printer.h" #elif RV64 #include "dynarec/rv64/rv64_printer.h" +#elif PPC64LE +#include "dynarec/ppc64le/ppc64le_printer.h" #endif #endif int sigbus_specialcases(siginfo_t* info, void * ucntx, void* pc, void* _fpsimd, dynablock_t* db, uintptr_t x64pc, int is32bits) @@ -497,6 +499,111 @@ int sigbus_specialcases(siginfo_t* info, void * ucntx, void* pc, void* _fpsimd, #undef GET_FIELD #undef SIGN_EXT +#elif PPC64LE + ucontext_t *p = (ucontext_t *)ucntx; + uint32_t inst = *(uint32_t*)pc; + uint32_t opcd = (inst >> 26) & 0x3F; + uint32_t rt_rs = (inst >> 21) & 0x1F; + uint32_t ra = (inst >> 16) & 0x1F; + + // D-form stores: STH (44), STW (36) + if(opcd == 44 || opcd == 36) { + int16_t disp = (int16_t)(inst & 0xFFFF); + int size = (opcd == 44) ? 2 : 4; + volatile uint8_t* addr = (void*)(p->uc_mcontext.gp_regs[ra] + disp); + if(is32bits) addr = (uint8_t*)(((uintptr_t)addr)&0xffffffff); + uint64_t value = p->uc_mcontext.gp_regs[rt_rs]; + for(int i=0; i>(i*8))&0xff; + p->uc_mcontext.gp_regs[PT_NIP]+=4; + return 1; + } + // DS-form store: STD (opcd=62, xo=0) + if(opcd == 62 && (inst & 0x3) == 0) { + int16_t ds = (int16_t)(inst & 0xFFFC); + volatile uint8_t* addr = (void*)(p->uc_mcontext.gp_regs[ra] + ds); + if(is32bits) addr = (uint8_t*)(((uintptr_t)addr)&0xffffffff); + uint64_t value = p->uc_mcontext.gp_regs[rt_rs]; + if((((uintptr_t)addr)&3)==0) { + for(int i=0; i<2; ++i) + ((volatile uint32_t*)addr)[i] = (value>>(i*32))&0xffffffff; + } else + for(int i=0; i<8; ++i) + addr[i] = (value>>(i*8))&0xff; + p->uc_mcontext.gp_regs[PT_NIP]+=4; + return 1; + } + // D-form loads: LHZ (40), LWZ (32) + if(opcd == 40 || opcd == 32) { + int16_t disp = (int16_t)(inst & 0xFFFF); + int size = (opcd == 40) ? 2 : 4; + volatile uint8_t* addr = (void*)(p->uc_mcontext.gp_regs[ra] + disp); + if(is32bits) addr = (uint8_t*)(((uintptr_t)addr)&0xffffffff); + uint64_t value = 0; + for(int i=0; iuc_mcontext.gp_regs[rt_rs] = value; + p->uc_mcontext.gp_regs[PT_NIP]+=4; + return 1; + } + // DS-form load: LD (opcd=58, xo=0) + if(opcd == 58 && (inst & 0x3) == 0) { + int16_t ds = (int16_t)(inst & 0xFFFC); + volatile uint8_t* addr = (void*)(p->uc_mcontext.gp_regs[ra] + ds); + if(is32bits) addr = (uint8_t*)(((uintptr_t)addr)&0xffffffff); + uint64_t value = 0; + if((((uintptr_t)addr)&3)==0) { + for(int i=0; i<2; ++i) + value |= ((uint64_t)((volatile uint32_t*)addr)[i]) << (i*32); + } else + for(int i=0; i<8; ++i) + value |= ((uint64_t)addr[i]) << (i*8); + p->uc_mcontext.gp_regs[rt_rs] = value; + p->uc_mcontext.gp_regs[PT_NIP]+=4; + return 1; + } + // X-form (opcd=31): indexed loads/stores + if(opcd == 31) { + uint32_t xo = (inst >> 1) & 0x3FF; + uint32_t rb = (inst >> 11) & 0x1F; + uint64_t ea = p->uc_mcontext.gp_regs[ra] + p->uc_mcontext.gp_regs[rb]; + volatile uint8_t* addr = (void*)ea; + if(is32bits) addr = (uint8_t*)(((uintptr_t)addr)&0xffffffff); + int size = 0; + int is_store = 0; + switch(xo) { + case 279: size = 2; is_store = 0; break; // LHZX + case 23: size = 4; is_store = 0; break; // LWZX + case 21: size = 8; is_store = 0; break; // LDX + case 407: size = 2; is_store = 1; break; // STHX + case 151: size = 4; is_store = 1; break; // STWX + case 149: size = 8; is_store = 1; break; // STDX + default: size = 0; break; + } + if(size) { + if(is_store) { + uint64_t value = p->uc_mcontext.gp_regs[rt_rs]; + if(size==8 && (((uintptr_t)addr)&3)==0) { + for(int i=0; i<2; ++i) + ((volatile uint32_t*)addr)[i] = (value>>(i*32))&0xffffffff; + } else + for(int i=0; i>(i*8))&0xff; + } else { + uint64_t value = 0; + if(size==8 && (((uintptr_t)addr)&3)==0) { + for(int i=0; i<2; ++i) + value |= ((uint64_t)((volatile uint32_t*)addr)[i]) << (i*32); + } else + for(int i=0; iuc_mcontext.gp_regs[rt_rs] = value; + } + p->uc_mcontext.gp_regs[PT_NIP]+=4; + return 1; + } + } + printf_log(LOG_INFO, "Unsupported SIGBUS special cases with pc=%p, opcode=%x (%s)\n", pc, inst, ppc64le_print(inst, (uintptr_t)pc)); #endif return 0; #undef CHECK diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt index 3de0b1f04..b24f8619a 100644 --- a/src/wrapped/generated/functions_list.txt +++ b/src/wrapped/generated/functions_list.txt @@ -4187,6 +4187,8 @@ #() iFEpuvvppp -> iFEpuppp wrappedalure: wrappedalut: +wrappedandroidshmem: +wrappedandroidsupport: wrappedanl: wrappedatk: - vFp: @@ -5336,6 +5338,7 @@ wrappedgtkx112: - pFpipppppppi: - gtk_toolbar_insert_element wrappedharfbuzzsubset: +wrappediconv: wrappedicui18n64: wrappedicui18n66: wrappedicui18n67: @@ -7286,6 +7289,7 @@ wrappedtcmallocminimal: - pFpLiiil: - mmap - mmap64 +wrappedtermuxexec: wrappedudev0: wrappedudev1: - vFpp: diff --git a/src/wrapped/generated/wrappedandroidsupportdefs.h b/src/wrapped/generated/wrappedandroidsupportdefs.h index 01a1d8b6e..a2244b5e6 100644 --- a/src/wrapped/generated/wrappedandroidsupportdefs.h +++ b/src/wrapped/generated/wrappedandroidsupportdefs.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappedandroidsupportDEFS_H_ #define __wrappedandroidsupportDEFS_H_ diff --git a/src/wrapped/generated/wrappedandroidsupporttypes.h b/src/wrapped/generated/wrappedandroidsupporttypes.h index 1f85cb664..e81cff0db 100644 --- a/src/wrapped/generated/wrappedandroidsupporttypes.h +++ b/src/wrapped/generated/wrappedandroidsupporttypes.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappedandroidsupportTYPES_H_ #define __wrappedandroidsupportTYPES_H_ diff --git a/src/wrapped/generated/wrappedandroidsupportundefs.h b/src/wrapped/generated/wrappedandroidsupportundefs.h index 1d78d88eb..64afadd8a 100644 --- a/src/wrapped/generated/wrappedandroidsupportundefs.h +++ b/src/wrapped/generated/wrappedandroidsupportundefs.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappedandroidsupportUNDEFS_H_ #define __wrappedandroidsupportUNDEFS_H_ diff --git a/src/wrapped/generated/wrappediconvdefs.h b/src/wrapped/generated/wrappediconvdefs.h index db777bd15..48ee02ad5 100644 --- a/src/wrapped/generated/wrappediconvdefs.h +++ b/src/wrapped/generated/wrappediconvdefs.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappediconvDEFS_H_ #define __wrappediconvDEFS_H_ diff --git a/src/wrapped/generated/wrappediconvtypes.h b/src/wrapped/generated/wrappediconvtypes.h index 4bd1a7151..0d8e5a48e 100644 --- a/src/wrapped/generated/wrappediconvtypes.h +++ b/src/wrapped/generated/wrappediconvtypes.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappediconvTYPES_H_ #define __wrappediconvTYPES_H_ diff --git a/src/wrapped/generated/wrappediconvundefs.h b/src/wrapped/generated/wrappediconvundefs.h index 36d2c9624..98bf08e17 100644 --- a/src/wrapped/generated/wrappediconvundefs.h +++ b/src/wrapped/generated/wrappediconvundefs.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappediconvUNDEFS_H_ #define __wrappediconvUNDEFS_H_ diff --git a/src/wrapped/generated/wrappedtermuxexecdefs.h b/src/wrapped/generated/wrappedtermuxexecdefs.h index b4d1f1a8c..d5cfe7b21 100644 --- a/src/wrapped/generated/wrappedtermuxexecdefs.h +++ b/src/wrapped/generated/wrappedtermuxexecdefs.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappedtermuxexecDEFS_H_ #define __wrappedtermuxexecDEFS_H_ diff --git a/src/wrapped/generated/wrappedtermuxexectypes.h b/src/wrapped/generated/wrappedtermuxexectypes.h index 26ec059cd..7b9d2b597 100644 --- a/src/wrapped/generated/wrappedtermuxexectypes.h +++ b/src/wrapped/generated/wrappedtermuxexectypes.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappedtermuxexecTYPES_H_ #define __wrappedtermuxexecTYPES_H_ diff --git a/src/wrapped/generated/wrappedtermuxexecundefs.h b/src/wrapped/generated/wrappedtermuxexecundefs.h index 83bf26c2c..316730d53 100644 --- a/src/wrapped/generated/wrappedtermuxexecundefs.h +++ b/src/wrapped/generated/wrappedtermuxexecundefs.h @@ -1,5 +1,5 @@ /******************************************************************* - * File automatically generated by rebuild_wrappers.py (v2.2.0.18) * + * File automatically generated by rebuild_wrappers.py (v2.5.0.24) * *******************************************************************/ #ifndef __wrappedtermuxexecUNDEFS_H_ #define __wrappedtermuxexecUNDEFS_H_ diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c index 0375fed83..fed8c30d2 100644 --- a/src/wrapped/generated/wrapper.c +++ b/src/wrapped/generated/wrapper.c @@ -15754,6 +15754,2414 @@ int isSimpleWrapper(wrapper_t fun) { #endif return 0; } +#elif defined(PPC64LE) +int isSimpleWrapper(wrapper_t fun) { + if (box64_is32bits) return 0; + if (fun == &vFv) return 1; + if (fun == &vFc) return 17; + if (fun == &vFw) return 17; + if (fun == &vFi) return 17; + if (fun == &vFC) return 1; + if (fun == &vFW) return 1; + if (fun == &vFu) return 17; + if (fun == &vFU) return 1; + if (fun == &vFf) return 2; + if (fun == &vFd) return 2; + if (fun == &vFl) return 1; + if (fun == &vFL) return 1; + if (fun == &vFp) return 1; + if (fun == &cFv) return 1; + if (fun == &cFc) return 17; + if (fun == &cFi) return 17; + if (fun == &cFu) return 17; + if (fun == &cFf) return 2; + if (fun == &cFp) return 1; + if (fun == &wFp) return 1; + if (fun == &iFv) return 1; + if (fun == &iFc) return 17; + if (fun == &iFw) return 17; + if (fun == &iFi) return 17; + if (fun == &iFI) return 1; + if (fun == &iFC) return 1; + if (fun == &iFW) return 1; + if (fun == &iFu) return 17; + if (fun == &iFU) return 1; + if (fun == &iFf) return 2; + if (fun == &iFd) return 2; + if (fun == &iFl) return 1; + if (fun == &iFL) return 1; + if (fun == &iFp) return 1; + if (fun == &IFv) return 1; + if (fun == &IFi) return 17; + if (fun == &IFI) return 1; + if (fun == &IFf) return 2; + if (fun == &IFd) return 2; + if (fun == &IFp) return 1; + if (fun == &CFv) return 1; + if (fun == &CFi) return 17; + if (fun == &CFW) return 1; + if (fun == &CFu) return 17; + if (fun == &CFU) return 1; + if (fun == &CFl) return 1; + if (fun == &CFL) return 1; + if (fun == &CFp) return 1; + if (fun == &WFv) return 1; + if (fun == &WFi) return 17; + if (fun == &WFW) return 1; + if (fun == &WFu) return 17; + if (fun == &WFp) return 1; + if (fun == &uFv) return 1; + if (fun == &uFi) return 17; + if (fun == &uFC) return 1; + if (fun == &uFu) return 17; + if (fun == &uFU) return 1; + if (fun == &uFd) return 2; + if (fun == &uFL) return 1; + if (fun == &uFp) return 1; + if (fun == &UFv) return 1; + if (fun == &UFi) return 17; + if (fun == &UFu) return 17; + if (fun == &UFp) return 1; + if (fun == &fFv) return -1; + if (fun == &fFi) return -17; + if (fun == &fFu) return -17; + if (fun == &fFf) return -2; + if (fun == &fFp) return -1; + if (fun == &dFv) return -1; + if (fun == &dFi) return -17; + if (fun == &dFu) return -17; + if (fun == &dFd) return -2; + if (fun == &dFL) return -1; + if (fun == &dFp) return -1; + if (fun == &lFv) return 1; + if (fun == &lFi) return 17; + if (fun == &lFu) return 17; + if (fun == &lFf) return 2; + if (fun == &lFd) return 2; + if (fun == &lFl) return 1; + if (fun == &lFp) return 1; + if (fun == &LFv) return 1; + if (fun == &LFi) return 17; + if (fun == &LFu) return 17; + if (fun == &LFd) return 2; + if (fun == &LFL) return 1; + if (fun == &LFp) return 1; + if (fun == &pFv) return 1; + if (fun == &pFw) return 17; + if (fun == &pFi) return 17; + if (fun == &pFI) return 1; + if (fun == &pFC) return 1; + if (fun == &pFW) return 1; + if (fun == &pFu) return 17; + if (fun == &pFU) return 1; + if (fun == &pFd) return 2; + if (fun == &pFl) return 1; + if (fun == &pFL) return 1; + if (fun == &pFp) return 1; + if (fun == &vFcc) return 49; + if (fun == &vFww) return 49; + if (fun == &vFii) return 49; + if (fun == &vFiI) return 17; + if (fun == &vFiW) return 17; + if (fun == &vFiu) return 49; + if (fun == &vFiU) return 17; + if (fun == &vFif) return 18; + if (fun == &vFid) return 18; + if (fun == &vFip) return 17; + if (fun == &vFWW) return 1; + if (fun == &vFWp) return 1; + if (fun == &vFuc) return 49; + if (fun == &vFuw) return 49; + if (fun == &vFui) return 49; + if (fun == &vFuI) return 17; + if (fun == &vFuC) return 17; + if (fun == &vFuW) return 17; + if (fun == &vFuu) return 49; + if (fun == &vFuU) return 17; + if (fun == &vFuf) return 18; + if (fun == &vFud) return 18; + if (fun == &vFul) return 17; + if (fun == &vFuL) return 17; + if (fun == &vFup) return 17; + if (fun == &vFUu) return 33; + if (fun == &vFfi) return 18; + if (fun == &vFfC) return 2; + if (fun == &vFff) return 3; + if (fun == &vFfp) return 2; + if (fun == &vFdd) return 3; + if (fun == &vFlu) return 33; + if (fun == &vFlp) return 1; + if (fun == &vFLu) return 33; + if (fun == &vFLL) return 1; + if (fun == &vFLp) return 1; + if (fun == &vFpc) return 33; + if (fun == &vFpi) return 33; + if (fun == &vFpI) return 1; + if (fun == &vFpC) return 1; + if (fun == &vFpW) return 1; + if (fun == &vFpu) return 33; + if (fun == &vFpU) return 1; + if (fun == &vFpf) return 2; + if (fun == &vFpd) return 2; + if (fun == &vFpl) return 1; + if (fun == &vFpL) return 1; + if (fun == &vFpp) return 1; + if (fun == &cFpi) return 33; + if (fun == &cFpp) return 1; + if (fun == &wFpi) return 33; + if (fun == &iFwp) return 17; + if (fun == &iFii) return 49; + if (fun == &iFiI) return 17; + if (fun == &iFiC) return 17; + if (fun == &iFiu) return 49; + if (fun == &iFiU) return 17; + if (fun == &iFil) return 17; + if (fun == &iFiL) return 17; + if (fun == &iFip) return 17; + if (fun == &iFIi) return 33; + if (fun == &iFWW) return 1; + if (fun == &iFui) return 49; + if (fun == &iFuu) return 49; + if (fun == &iFuf) return 18; + if (fun == &iFuL) return 17; + if (fun == &iFup) return 17; + if (fun == &iFUU) return 1; + if (fun == &iFUp) return 1; + if (fun == &iFff) return 3; + if (fun == &iFli) return 33; + if (fun == &iFlp) return 1; + if (fun == &iFLi) return 33; + if (fun == &iFLu) return 33; + if (fun == &iFLL) return 1; + if (fun == &iFLp) return 1; + if (fun == &iFpc) return 33; + if (fun == &iFpw) return 33; + if (fun == &iFpi) return 33; + if (fun == &iFpI) return 1; + if (fun == &iFpC) return 1; + if (fun == &iFpW) return 1; + if (fun == &iFpu) return 33; + if (fun == &iFpU) return 1; + if (fun == &iFpf) return 2; + if (fun == &iFpd) return 2; + if (fun == &iFpl) return 1; + if (fun == &iFpL) return 1; + if (fun == &iFpp) return 1; + if (fun == &IFip) return 17; + if (fun == &IFII) return 1; + if (fun == &IFuu) return 49; + if (fun == &IFpi) return 33; + if (fun == &IFpu) return 33; + if (fun == &IFpd) return 2; + if (fun == &IFpp) return 1; + if (fun == &CFip) return 17; + if (fun == &CFCi) return 33; + if (fun == &CFui) return 49; + if (fun == &CFuW) return 17; + if (fun == &CFuu) return 49; + if (fun == &CFuU) return 17; + if (fun == &CFpi) return 33; + if (fun == &CFpu) return 33; + if (fun == &CFpL) return 1; + if (fun == &CFpp) return 1; + if (fun == &WFpi) return 33; + if (fun == &WFpW) return 1; + if (fun == &WFpp) return 1; + if (fun == &uFii) return 49; + if (fun == &uFiu) return 49; + if (fun == &uFip) return 17; + if (fun == &uFui) return 49; + if (fun == &uFuu) return 49; + if (fun == &uFuL) return 17; + if (fun == &uFup) return 17; + if (fun == &uFUi) return 33; + if (fun == &uFUL) return 1; + if (fun == &uFUp) return 1; + if (fun == &uFpw) return 33; + if (fun == &uFpi) return 33; + if (fun == &uFpC) return 1; + if (fun == &uFpu) return 33; + if (fun == &uFpU) return 1; + if (fun == &uFpf) return 2; + if (fun == &uFpl) return 1; + if (fun == &uFpL) return 1; + if (fun == &uFpp) return 1; + if (fun == &UFii) return 49; + if (fun == &UFuu) return 49; + if (fun == &UFUU) return 1; + if (fun == &UFUp) return 1; + if (fun == &UFdi) return 18; + if (fun == &UFpi) return 33; + if (fun == &UFpu) return 33; + if (fun == &UFpU) return 1; + if (fun == &UFpL) return 1; + if (fun == &UFpp) return 1; + if (fun == &fFif) return -18; + if (fun == &fFfi) return -18; + if (fun == &fFff) return -3; + if (fun == &fFfp) return -2; + if (fun == &fFpi) return -33; + if (fun == &fFpu) return -33; + if (fun == &fFpf) return -2; + if (fun == &fFpL) return -1; + if (fun == &fFpp) return -1; + if (fun == &dFid) return -18; + if (fun == &dFud) return -18; + if (fun == &dFdi) return -18; + if (fun == &dFdd) return -3; + if (fun == &dFdp) return -2; + if (fun == &dFll) return -1; + if (fun == &dFpi) return -33; + if (fun == &dFpu) return -33; + if (fun == &dFpd) return -2; + if (fun == &dFpL) return -1; + if (fun == &dFpp) return -1; + if (fun == &lFii) return 49; + if (fun == &lFiL) return 17; + if (fun == &lFip) return 17; + if (fun == &lFui) return 49; + if (fun == &lFll) return 1; + if (fun == &lFpi) return 33; + if (fun == &lFpu) return 33; + if (fun == &lFpd) return 2; + if (fun == &lFpl) return 1; + if (fun == &lFpL) return 1; + if (fun == &lFpp) return 1; + if (fun == &LFiL) return 17; + if (fun == &LFUU) return 1; + if (fun == &LFUp) return 1; + if (fun == &LFLi) return 33; + if (fun == &LFLu) return 33; + if (fun == &LFLL) return 1; + if (fun == &LFLp) return 1; + if (fun == &LFpi) return 33; + if (fun == &LFpu) return 33; + if (fun == &LFpU) return 1; + if (fun == &LFpl) return 1; + if (fun == &LFpL) return 1; + if (fun == &LFpp) return 1; + if (fun == &pFii) return 49; + if (fun == &pFiu) return 49; + if (fun == &pFip) return 17; + if (fun == &pFWW) return 1; + if (fun == &pFui) return 49; + if (fun == &pFuu) return 49; + if (fun == &pFud) return 18; + if (fun == &pFul) return 17; + if (fun == &pFuL) return 17; + if (fun == &pFup) return 17; + if (fun == &pFUp) return 1; + if (fun == &pFdu) return 18; + if (fun == &pFdd) return 3; + if (fun == &pFli) return 33; + if (fun == &pFll) return 1; + if (fun == &pFlp) return 1; + if (fun == &pFLc) return 33; + if (fun == &pFLi) return 33; + if (fun == &pFLu) return 33; + if (fun == &pFLL) return 1; + if (fun == &pFLp) return 1; + if (fun == &pFpc) return 33; + if (fun == &pFpi) return 33; + if (fun == &pFpI) return 1; + if (fun == &pFpC) return 1; + if (fun == &pFpW) return 1; + if (fun == &pFpu) return 33; + if (fun == &pFpU) return 1; + if (fun == &pFpf) return 2; + if (fun == &pFpd) return 2; + if (fun == &pFpl) return 1; + if (fun == &pFpL) return 1; + if (fun == &pFpp) return 1; + if (fun == &vFccc) return 113; + if (fun == &vFwww) return 113; + if (fun == &vFiii) return 113; + if (fun == &vFiif) return 50; + if (fun == &vFiip) return 49; + if (fun == &vFiII) return 17; + if (fun == &vFiui) return 113; + if (fun == &vFiuu) return 113; + if (fun == &vFiup) return 49; + if (fun == &vFiUU) return 17; + if (fun == &vFiff) return 19; + if (fun == &vFidd) return 19; + if (fun == &vFilu) return 81; + if (fun == &vFill) return 17; + if (fun == &vFilp) return 17; + if (fun == &vFipi) return 81; + if (fun == &vFipu) return 81; + if (fun == &vFipL) return 17; + if (fun == &vFipp) return 17; + if (fun == &vFIpp) return 1; + if (fun == &vFCCC) return 1; + if (fun == &vFWWW) return 1; + if (fun == &vFucc) return 113; + if (fun == &vFuww) return 113; + if (fun == &vFuii) return 113; + if (fun == &vFuiI) return 49; + if (fun == &vFuiu) return 113; + if (fun == &vFuiU) return 49; + if (fun == &vFuif) return 50; + if (fun == &vFuid) return 50; + if (fun == &vFuip) return 49; + if (fun == &vFuII) return 17; + if (fun == &vFuWW) return 17; + if (fun == &vFuui) return 113; + if (fun == &vFuuC) return 49; + if (fun == &vFuuu) return 113; + if (fun == &vFuuU) return 49; + if (fun == &vFuuf) return 50; + if (fun == &vFuud) return 50; + if (fun == &vFuup) return 49; + if (fun == &vFuUU) return 17; + if (fun == &vFuff) return 19; + if (fun == &vFufp) return 18; + if (fun == &vFudd) return 19; + if (fun == &vFull) return 17; + if (fun == &vFulp) return 17; + if (fun == &vFuLp) return 17; + if (fun == &vFupu) return 81; + if (fun == &vFupL) return 17; + if (fun == &vFupp) return 17; + if (fun == &vFfff) return 4; + if (fun == &vFfpp) return 2; + if (fun == &vFddd) return 4; + if (fun == &vFdpp) return 2; + if (fun == &vFlii) return 97; + if (fun == &vFlip) return 33; + if (fun == &vFllp) return 1; + if (fun == &vFlpp) return 1; + if (fun == &vFLup) return 33; + if (fun == &vFLpL) return 1; + if (fun == &vFLpp) return 1; + if (fun == &vFpcu) return 97; + if (fun == &vFpww) return 97; + if (fun == &vFpic) return 97; + if (fun == &vFpii) return 97; + if (fun == &vFpiC) return 33; + if (fun == &vFpiu) return 97; + if (fun == &vFpif) return 34; + if (fun == &vFpid) return 34; + if (fun == &vFpiL) return 33; + if (fun == &vFpip) return 33; + if (fun == &vFpCu) return 65; + if (fun == &vFpui) return 97; + if (fun == &vFpuI) return 33; + if (fun == &vFpuC) return 33; + if (fun == &vFpuW) return 33; + if (fun == &vFpuu) return 97; + if (fun == &vFpuU) return 33; + if (fun == &vFpuf) return 34; + if (fun == &vFpud) return 34; + if (fun == &vFpul) return 33; + if (fun == &vFpuL) return 33; + if (fun == &vFpup) return 33; + if (fun == &vFpUU) return 1; + if (fun == &vFpUp) return 1; + if (fun == &vFpff) return 3; + if (fun == &vFpdu) return 34; + if (fun == &vFpdd) return 3; + if (fun == &vFpdp) return 2; + if (fun == &vFpll) return 1; + if (fun == &vFplL) return 1; + if (fun == &vFplp) return 1; + if (fun == &vFpLi) return 65; + if (fun == &vFpLu) return 65; + if (fun == &vFpLL) return 1; + if (fun == &vFpLp) return 1; + if (fun == &vFppi) return 65; + if (fun == &vFppu) return 65; + if (fun == &vFppU) return 1; + if (fun == &vFppf) return 2; + if (fun == &vFppd) return 2; + if (fun == &vFppl) return 1; + if (fun == &vFppL) return 1; + if (fun == &vFppp) return 1; + if (fun == &cFpdp) return 2; + if (fun == &wFppp) return 1; + if (fun == &iFwww) return 113; + if (fun == &iFwpp) return 17; + if (fun == &iFiwC) return 49; + if (fun == &iFiii) return 113; + if (fun == &iFiiI) return 49; + if (fun == &iFiiu) return 113; + if (fun == &iFiiU) return 49; + if (fun == &iFiil) return 49; + if (fun == &iFiip) return 49; + if (fun == &iFiII) return 17; + if (fun == &iFiCC) return 17; + if (fun == &iFiui) return 113; + if (fun == &iFiuu) return 113; + if (fun == &iFiuL) return 49; + if (fun == &iFiup) return 49; + if (fun == &iFiUU) return 17; + if (fun == &iFiUp) return 17; + if (fun == &iFidd) return 19; + if (fun == &iFill) return 17; + if (fun == &iFilp) return 17; + if (fun == &iFiLi) return 81; + if (fun == &iFiLp) return 17; + if (fun == &iFipi) return 81; + if (fun == &iFipu) return 81; + if (fun == &iFipL) return 17; + if (fun == &iFipp) return 17; + if (fun == &iFIii) return 97; + if (fun == &iFIpi) return 65; + if (fun == &iFCuW) return 33; + if (fun == &iFuwp) return 49; + if (fun == &iFuip) return 49; + if (fun == &iFuWp) return 17; + if (fun == &iFuui) return 113; + if (fun == &iFuuu) return 113; + if (fun == &iFuuU) return 49; + if (fun == &iFuup) return 49; + if (fun == &iFuLL) return 17; + if (fun == &iFuLp) return 17; + if (fun == &iFupi) return 81; + if (fun == &iFupI) return 17; + if (fun == &iFupu) return 81; + if (fun == &iFupf) return 18; + if (fun == &iFupL) return 17; + if (fun == &iFupp) return 17; + if (fun == &iFUpp) return 1; + if (fun == &iFfff) return 4; + if (fun == &iFLpi) return 65; + if (fun == &iFLpL) return 1; + if (fun == &iFLpp) return 1; + if (fun == &iFpcU) return 33; + if (fun == &iFpcp) return 33; + if (fun == &iFpwp) return 33; + if (fun == &iFpiw) return 97; + if (fun == &iFpii) return 97; + if (fun == &iFpiI) return 33; + if (fun == &iFpiC) return 33; + if (fun == &iFpiW) return 33; + if (fun == &iFpiu) return 97; + if (fun == &iFpiU) return 33; + if (fun == &iFpid) return 34; + if (fun == &iFpil) return 33; + if (fun == &iFpiL) return 33; + if (fun == &iFpip) return 33; + if (fun == &iFpIi) return 65; + if (fun == &iFpIp) return 1; + if (fun == &iFpCu) return 65; + if (fun == &iFpCp) return 1; + if (fun == &iFpWW) return 1; + if (fun == &iFpWu) return 65; + if (fun == &iFpWp) return 1; + if (fun == &iFpui) return 97; + if (fun == &iFpuC) return 33; + if (fun == &iFpuu) return 97; + if (fun == &iFpuU) return 33; + if (fun == &iFpuf) return 34; + if (fun == &iFpul) return 33; + if (fun == &iFpuL) return 33; + if (fun == &iFpup) return 33; + if (fun == &iFpUu) return 65; + if (fun == &iFpUU) return 1; + if (fun == &iFpUp) return 1; + if (fun == &iFpfu) return 34; + if (fun == &iFpff) return 3; + if (fun == &iFpdd) return 3; + if (fun == &iFpli) return 65; + if (fun == &iFpll) return 1; + if (fun == &iFplL) return 1; + if (fun == &iFplp) return 1; + if (fun == &iFpLi) return 65; + if (fun == &iFpLu) return 65; + if (fun == &iFpLf) return 2; + if (fun == &iFpLl) return 1; + if (fun == &iFpLL) return 1; + if (fun == &iFpLp) return 1; + if (fun == &iFppc) return 65; + if (fun == &iFppi) return 65; + if (fun == &iFppI) return 1; + if (fun == &iFppC) return 1; + if (fun == &iFppW) return 1; + if (fun == &iFppu) return 65; + if (fun == &iFppU) return 1; + if (fun == &iFppf) return 2; + if (fun == &iFppd) return 2; + if (fun == &iFppl) return 1; + if (fun == &iFppL) return 1; + if (fun == &iFppp) return 1; + if (fun == &IFiIi) return 81; + if (fun == &IFIII) return 1; + if (fun == &IFIUU) return 1; + if (fun == &IFupI) return 17; + if (fun == &IFUUU) return 1; + if (fun == &IFpIi) return 65; + if (fun == &IFpIu) return 65; + if (fun == &IFppi) return 65; + if (fun == &IFppI) return 1; + if (fun == &CFipp) return 17; + if (fun == &CFuUu) return 81; + if (fun == &CFuff) return 19; + if (fun == &CFppp) return 1; + if (fun == &WFWpL) return 1; + if (fun == &WFpip) return 33; + if (fun == &WFppp) return 1; + if (fun == &uFiuu) return 113; + if (fun == &uFiup) return 49; + if (fun == &uFilp) return 17; + if (fun == &uFipu) return 81; + if (fun == &uFipL) return 17; + if (fun == &uFipp) return 17; + if (fun == &uFuii) return 113; + if (fun == &uFuip) return 49; + if (fun == &uFuCC) return 17; + if (fun == &uFuWi) return 81; + if (fun == &uFuuu) return 113; + if (fun == &uFuup) return 49; + if (fun == &uFufp) return 18; + if (fun == &uFupu) return 81; + if (fun == &uFupU) return 17; + if (fun == &uFupL) return 17; + if (fun == &uFupp) return 17; + if (fun == &uFUCL) return 1; + if (fun == &uFUWL) return 1; + if (fun == &uFUuL) return 33; + if (fun == &uFUUL) return 1; + if (fun == &uFUpL) return 1; + if (fun == &uFpii) return 97; + if (fun == &uFpiu) return 97; + if (fun == &uFpif) return 34; + if (fun == &uFpip) return 33; + if (fun == &uFpCi) return 65; + if (fun == &uFpWi) return 65; + if (fun == &uFpWu) return 65; + if (fun == &uFpWf) return 2; + if (fun == &uFpWp) return 1; + if (fun == &uFpui) return 97; + if (fun == &uFpuW) return 33; + if (fun == &uFpuu) return 97; + if (fun == &uFpuU) return 33; + if (fun == &uFpuL) return 33; + if (fun == &uFpup) return 33; + if (fun == &uFpUu) return 65; + if (fun == &uFpUL) return 1; + if (fun == &uFpUp) return 1; + if (fun == &uFpfu) return 34; + if (fun == &uFpff) return 3; + if (fun == &uFpli) return 65; + if (fun == &uFplu) return 65; + if (fun == &uFpLi) return 65; + if (fun == &uFpLu) return 65; + if (fun == &uFpLL) return 1; + if (fun == &uFpLp) return 1; + if (fun == &uFppi) return 65; + if (fun == &uFppu) return 65; + if (fun == &uFppU) return 1; + if (fun == &uFppL) return 1; + if (fun == &uFppp) return 1; + if (fun == &UFpup) return 33; + if (fun == &UFppi) return 65; + if (fun == &fFuii) return -113; + if (fun == &fFupf) return -18; + if (fun == &fFfff) return -4; + if (fun == &fFffp) return -3; + if (fun == &fFlpl) return -1; + if (fun == &fFppi) return -65; + if (fun == &fFppL) return -1; + if (fun == &fFppp) return -1; + if (fun == &dFuud) return -50; + if (fun == &dFddd) return -4; + if (fun == &dFddp) return -3; + if (fun == &dFlpl) return -1; + if (fun == &dFpii) return -97; + if (fun == &dFpdd) return -3; + if (fun == &dFppi) return -65; + if (fun == &dFppu) return -65; + if (fun == &dFppd) return -2; + if (fun == &dFppp) return -1; + if (fun == &lFiIL) return 17; + if (fun == &lFili) return 81; + if (fun == &lFipi) return 81; + if (fun == &lFipL) return 17; + if (fun == &lFlll) return 1; + if (fun == &lFlLl) return 1; + if (fun == &lFpip) return 33; + if (fun == &lFpup) return 33; + if (fun == &lFpli) return 65; + if (fun == &lFpLu) return 65; + if (fun == &lFpLd) return 2; + if (fun == &lFpLL) return 1; + if (fun == &lFpLp) return 1; + if (fun == &lFppi) return 65; + if (fun == &lFppu) return 65; + if (fun == &lFppl) return 1; + if (fun == &lFppL) return 1; + if (fun == &lFppp) return 1; + if (fun == &LFipL) return 17; + if (fun == &LFuui) return 113; + if (fun == &LFlpl) return 1; + if (fun == &LFLii) return 97; + if (fun == &LFLip) return 33; + if (fun == &LFLLl) return 1; + if (fun == &LFLLL) return 1; + if (fun == &LFLpu) return 65; + if (fun == &LFLpL) return 1; + if (fun == &LFpii) return 97; + if (fun == &LFpiU) return 33; + if (fun == &LFpip) return 33; + if (fun == &LFpCi) return 65; + if (fun == &LFpWp) return 1; + if (fun == &LFpui) return 97; + if (fun == &LFpuL) return 33; + if (fun == &LFpup) return 33; + if (fun == &LFpli) return 65; + if (fun == &LFplL) return 1; + if (fun == &LFpLi) return 65; + if (fun == &LFpLC) return 1; + if (fun == &LFpLL) return 1; + if (fun == &LFpLp) return 1; + if (fun == &LFppi) return 65; + if (fun == &LFppC) return 1; + if (fun == &LFppu) return 65; + if (fun == &LFppU) return 1; + if (fun == &LFppl) return 1; + if (fun == &LFppL) return 1; + if (fun == &LFppp) return 1; + if (fun == &pFiii) return 113; + if (fun == &pFiiu) return 113; + if (fun == &pFiif) return 50; + if (fun == &pFiid) return 50; + if (fun == &pFiip) return 49; + if (fun == &pFiuu) return 113; + if (fun == &pFiup) return 49; + if (fun == &pFiLL) return 17; + if (fun == &pFipi) return 81; + if (fun == &pFipL) return 17; + if (fun == &pFipp) return 17; + if (fun == &pFIpi) return 65; + if (fun == &pFCuW) return 33; + if (fun == &pFWWW) return 1; + if (fun == &pFWWp) return 1; + if (fun == &pFuip) return 49; + if (fun == &pFuCC) return 17; + if (fun == &pFuui) return 113; + if (fun == &pFuuu) return 113; + if (fun == &pFulu) return 81; + if (fun == &pFulp) return 17; + if (fun == &pFupi) return 81; + if (fun == &pFupu) return 81; + if (fun == &pFupl) return 17; + if (fun == &pFupL) return 17; + if (fun == &pFupp) return 17; + if (fun == &pFUpi) return 65; + if (fun == &pFdip) return 18; + if (fun == &pFddu) return 19; + if (fun == &pFddd) return 4; + if (fun == &pFdLL) return 2; + if (fun == &pFlpi) return 65; + if (fun == &pFLiu) return 97; + if (fun == &pFLup) return 33; + if (fun == &pFLLL) return 1; + if (fun == &pFLLp) return 1; + if (fun == &pFLpi) return 65; + if (fun == &pFLpp) return 1; + if (fun == &pFpcU) return 33; + if (fun == &pFpii) return 97; + if (fun == &pFpiu) return 97; + if (fun == &pFpif) return 34; + if (fun == &pFpid) return 34; + if (fun == &pFpil) return 33; + if (fun == &pFpiL) return 33; + if (fun == &pFpip) return 33; + if (fun == &pFpCi) return 65; + if (fun == &pFpWi) return 65; + if (fun == &pFpWW) return 1; + if (fun == &pFpWp) return 1; + if (fun == &pFpui) return 97; + if (fun == &pFpuu) return 97; + if (fun == &pFpuf) return 34; + if (fun == &pFpud) return 34; + if (fun == &pFpul) return 33; + if (fun == &pFpuL) return 33; + if (fun == &pFpup) return 33; + if (fun == &pFpdu) return 34; + if (fun == &pFpdd) return 3; + if (fun == &pFplc) return 65; + if (fun == &pFplu) return 65; + if (fun == &pFpll) return 1; + if (fun == &pFplp) return 1; + if (fun == &pFpLi) return 65; + if (fun == &pFpLu) return 65; + if (fun == &pFpLL) return 1; + if (fun == &pFpLp) return 1; + if (fun == &pFppc) return 65; + if (fun == &pFppi) return 65; + if (fun == &pFppu) return 65; + if (fun == &pFppf) return 2; + if (fun == &pFppd) return 2; + if (fun == &pFppl) return 1; + if (fun == &pFppL) return 1; + if (fun == &pFppp) return 1; + if (fun == &vFcccc) return 241; + if (fun == &vFwwww) return 241; + if (fun == &vFiiii) return 241; + if (fun == &vFiiip) return 113; + if (fun == &vFiiCp) return 49; + if (fun == &vFiill) return 49; + if (fun == &vFiIII) return 17; + if (fun == &vFiuip) return 113; + if (fun == &vFiuuu) return 241; + if (fun == &vFiulp) return 49; + if (fun == &vFiUUU) return 17; + if (fun == &vFifff) return 20; + if (fun == &vFiddd) return 20; + if (fun == &vFilip) return 81; + if (fun == &vFilpu) return 145; + if (fun == &vFilpp) return 17; + if (fun == &vFipii) return 209; + if (fun == &vFipup) return 81; + if (fun == &vFipll) return 17; + if (fun == &vFippL) return 17; + if (fun == &vFippp) return 17; + if (fun == &vFCCCC) return 1; + if (fun == &vFWWWW) return 1; + if (fun == &vFuccc) return 241; + if (fun == &vFuwww) return 241; + if (fun == &vFuiii) return 241; + if (fun == &vFuiip) return 113; + if (fun == &vFuiII) return 49; + if (fun == &vFuiui) return 241; + if (fun == &vFuiuC) return 113; + if (fun == &vFuiuu) return 241; + if (fun == &vFuiup) return 113; + if (fun == &vFuiUU) return 49; + if (fun == &vFuifi) return 114; + if (fun == &vFuiff) return 51; + if (fun == &vFuidd) return 51; + if (fun == &vFuilp) return 49; + if (fun == &vFuipi) return 177; + if (fun == &vFuipu) return 177; + if (fun == &vFuipp) return 49; + if (fun == &vFuIII) return 17; + if (fun == &vFuWWW) return 17; + if (fun == &vFuuii) return 241; + if (fun == &vFuuiu) return 241; + if (fun == &vFuuil) return 113; + if (fun == &vFuuip) return 113; + if (fun == &vFuuCu) return 177; + if (fun == &vFuuCp) return 49; + if (fun == &vFuuui) return 241; + if (fun == &vFuuuu) return 241; + if (fun == &vFuuuf) return 114; + if (fun == &vFuuud) return 114; + if (fun == &vFuuul) return 113; + if (fun == &vFuuup) return 113; + if (fun == &vFuuUl) return 49; + if (fun == &vFuuff) return 51; + if (fun == &vFuuli) return 177; + if (fun == &vFuupi) return 177; + if (fun == &vFuupp) return 49; + if (fun == &vFuUui) return 209; + if (fun == &vFuUup) return 81; + if (fun == &vFuUUU) return 17; + if (fun == &vFufff) return 20; + if (fun == &vFuddd) return 20; + if (fun == &vFuluU) return 81; + if (fun == &vFullC) return 17; + if (fun == &vFullp) return 17; + if (fun == &vFulpu) return 145; + if (fun == &vFulpp) return 17; + if (fun == &vFupii) return 209; + if (fun == &vFuppi) return 145; + if (fun == &vFuppu) return 145; + if (fun == &vFuppp) return 17; + if (fun == &vFUUpi) return 129; + if (fun == &vFffff) return 5; + if (fun == &vFdddd) return 5; + if (fun == &vFlfpl) return 2; + if (fun == &vFldpl) return 2; + if (fun == &vFllii) return 193; + if (fun == &vFlppl) return 1; + if (fun == &vFLiii) return 225; + if (fun == &vFLuui) return 225; + if (fun == &vFLppi) return 129; + if (fun == &vFLppl) return 1; + if (fun == &vFpwwu) return 225; + if (fun == &vFpiii) return 225; + if (fun == &vFpiiu) return 225; + if (fun == &vFpiiU) return 97; + if (fun == &vFpiid) return 98; + if (fun == &vFpiip) return 97; + if (fun == &vFpiui) return 225; + if (fun == &vFpiuL) return 97; + if (fun == &vFpiup) return 97; + if (fun == &vFpidd) return 35; + if (fun == &vFpiLu) return 161; + if (fun == &vFpiLL) return 33; + if (fun == &vFpipi) return 161; + if (fun == &vFpipu) return 161; + if (fun == &vFpipp) return 33; + if (fun == &vFpCuW) return 65; + if (fun == &vFpuii) return 225; + if (fun == &vFpuip) return 97; + if (fun == &vFpuCC) return 33; + if (fun == &vFpuuu) return 225; + if (fun == &vFpuup) return 97; + if (fun == &vFpufi) return 98; + if (fun == &vFpudd) return 35; + if (fun == &vFpuli) return 161; + if (fun == &vFpuLL) return 33; + if (fun == &vFpupu) return 161; + if (fun == &vFpupp) return 33; + if (fun == &vFpUuu) return 193; + if (fun == &vFpUUu) return 129; + if (fun == &vFpUpu) return 129; + if (fun == &vFpfff) return 4; + if (fun == &vFpdii) return 98; + if (fun == &vFpdup) return 34; + if (fun == &vFpddu) return 35; + if (fun == &vFpddd) return 4; + if (fun == &vFpdlL) return 2; + if (fun == &vFpldi) return 66; + if (fun == &vFplll) return 1; + if (fun == &vFpllL) return 1; + if (fun == &vFplpp) return 1; + if (fun == &vFpLii) return 193; + if (fun == &vFpLip) return 65; + if (fun == &vFpLuu) return 193; + if (fun == &vFpLLL) return 1; + if (fun == &vFpLLp) return 1; + if (fun == &vFpLpi) return 129; + if (fun == &vFpLpu) return 129; + if (fun == &vFpLpL) return 1; + if (fun == &vFpLpp) return 1; + if (fun == &vFppii) return 193; + if (fun == &vFppiu) return 193; + if (fun == &vFppid) return 66; + if (fun == &vFppil) return 65; + if (fun == &vFppiL) return 65; + if (fun == &vFppip) return 65; + if (fun == &vFppui) return 193; + if (fun == &vFppuu) return 193; + if (fun == &vFppup) return 65; + if (fun == &vFppUu) return 129; + if (fun == &vFppfi) return 66; + if (fun == &vFppff) return 3; + if (fun == &vFppdu) return 66; + if (fun == &vFppdd) return 3; + if (fun == &vFppdp) return 2; + if (fun == &vFpplL) return 1; + if (fun == &vFpplp) return 1; + if (fun == &vFppLL) return 1; + if (fun == &vFppLp) return 1; + if (fun == &vFpppi) return 129; + if (fun == &vFpppu) return 129; + if (fun == &vFpppd) return 2; + if (fun == &vFpppl) return 1; + if (fun == &vFpppL) return 1; + if (fun == &vFpppp) return 1; + if (fun == &cFpiii) return 225; + if (fun == &cFpipp) return 33; + if (fun == &iFwwww) return 241; + if (fun == &iFwppp) return 17; + if (fun == &iFiiii) return 241; + if (fun == &iFiiiu) return 241; + if (fun == &iFiiip) return 113; + if (fun == &iFiiII) return 49; + if (fun == &iFiiui) return 241; + if (fun == &iFiill) return 49; + if (fun == &iFiipi) return 177; + if (fun == &iFiipp) return 49; + if (fun == &iFiIIi) return 145; + if (fun == &iFiIIu) return 145; + if (fun == &iFiWii) return 209; + if (fun == &iFiuwp) return 113; + if (fun == &iFiuii) return 241; + if (fun == &iFiuuU) return 113; + if (fun == &iFiuup) return 113; + if (fun == &iFiupu) return 177; + if (fun == &iFiupp) return 49; + if (fun == &iFilli) return 145; + if (fun == &iFiLpL) return 17; + if (fun == &iFipii) return 209; + if (fun == &iFipip) return 81; + if (fun == &iFipWp) return 17; + if (fun == &iFipui) return 209; + if (fun == &iFipuU) return 81; + if (fun == &iFipup) return 81; + if (fun == &iFipLi) return 145; + if (fun == &iFipLu) return 145; + if (fun == &iFipLp) return 17; + if (fun == &iFippi) return 145; + if (fun == &iFippu) return 145; + if (fun == &iFippl) return 17; + if (fun == &iFippL) return 17; + if (fun == &iFippp) return 17; + if (fun == &iFIUIU) return 1; + if (fun == &iFuiup) return 113; + if (fun == &iFuipp) return 49; + if (fun == &iFuWWp) return 17; + if (fun == &iFuuip) return 113; + if (fun == &iFuuuu) return 241; + if (fun == &iFuuup) return 113; + if (fun == &iFuupi) return 177; + if (fun == &iFuupu) return 177; + if (fun == &iFuupp) return 49; + if (fun == &iFupLp) return 17; + if (fun == &iFuppi) return 145; + if (fun == &iFuppu) return 145; + if (fun == &iFuppp) return 17; + if (fun == &iFLpLp) return 1; + if (fun == &iFLppp) return 1; + if (fun == &iFpcLp) return 33; + if (fun == &iFpcpu) return 161; + if (fun == &iFpcpL) return 33; + if (fun == &iFpcpp) return 33; + if (fun == &iFpwww) return 225; + if (fun == &iFpwpp) return 33; + if (fun == &iFpiww) return 225; + if (fun == &iFpiii) return 225; + if (fun == &iFpiiC) return 97; + if (fun == &iFpiiu) return 225; + if (fun == &iFpiid) return 98; + if (fun == &iFpiiL) return 97; + if (fun == &iFpiip) return 97; + if (fun == &iFpiIi) return 161; + if (fun == &iFpiCp) return 33; + if (fun == &iFpiuu) return 225; + if (fun == &iFpiuL) return 97; + if (fun == &iFpiup) return 97; + if (fun == &iFpiUU) return 33; + if (fun == &iFpili) return 161; + if (fun == &iFpild) return 34; + if (fun == &iFpiLL) return 33; + if (fun == &iFpipi) return 161; + if (fun == &iFpipu) return 161; + if (fun == &iFpipL) return 33; + if (fun == &iFpipp) return 33; + if (fun == &iFpIip) return 65; + if (fun == &iFpCCC) return 1; + if (fun == &iFpCCp) return 1; + if (fun == &iFpCuu) return 193; + if (fun == &iFpCpi) return 129; + if (fun == &iFpCpu) return 129; + if (fun == &iFpCpp) return 1; + if (fun == &iFpWWW) return 1; + if (fun == &iFpWWu) return 129; + if (fun == &iFpWpp) return 1; + if (fun == &iFpuwp) return 97; + if (fun == &iFpuii) return 225; + if (fun == &iFpuiu) return 225; + if (fun == &iFpuiL) return 97; + if (fun == &iFpuip) return 97; + if (fun == &iFpuII) return 33; + if (fun == &iFpuCp) return 33; + if (fun == &iFpuWp) return 33; + if (fun == &iFpuui) return 225; + if (fun == &iFpuuu) return 225; + if (fun == &iFpuuU) return 97; + if (fun == &iFpuul) return 97; + if (fun == &iFpuuL) return 97; + if (fun == &iFpuup) return 97; + if (fun == &iFpufp) return 34; + if (fun == &iFpuLi) return 161; + if (fun == &iFpuLL) return 33; + if (fun == &iFpuLp) return 33; + if (fun == &iFpupi) return 161; + if (fun == &iFpupC) return 33; + if (fun == &iFpupu) return 161; + if (fun == &iFpupl) return 33; + if (fun == &iFpupL) return 33; + if (fun == &iFpupp) return 33; + if (fun == &iFpUup) return 65; + if (fun == &iFpUUu) return 129; + if (fun == &iFpUpp) return 1; + if (fun == &iFpfii) return 98; + if (fun == &iFpfff) return 4; + if (fun == &iFpffp) return 3; + if (fun == &iFpdip) return 34; + if (fun == &iFplii) return 193; + if (fun == &iFplip) return 65; + if (fun == &iFplll) return 1; + if (fun == &iFpllp) return 1; + if (fun == &iFplpi) return 129; + if (fun == &iFplpp) return 1; + if (fun == &iFpLii) return 193; + if (fun == &iFpLiL) return 65; + if (fun == &iFpLip) return 65; + if (fun == &iFpLCp) return 1; + if (fun == &iFpLui) return 193; + if (fun == &iFpLuu) return 193; + if (fun == &iFpLup) return 65; + if (fun == &iFpLlp) return 1; + if (fun == &iFpLLu) return 129; + if (fun == &iFpLLL) return 1; + if (fun == &iFpLLp) return 1; + if (fun == &iFpLpi) return 129; + if (fun == &iFpLpu) return 129; + if (fun == &iFpLpf) return 2; + if (fun == &iFpLpd) return 2; + if (fun == &iFpLpL) return 1; + if (fun == &iFpLpp) return 1; + if (fun == &iFppcc) return 193; + if (fun == &iFppii) return 193; + if (fun == &iFppiI) return 65; + if (fun == &iFppiu) return 193; + if (fun == &iFppiU) return 65; + if (fun == &iFppiL) return 65; + if (fun == &iFppip) return 65; + if (fun == &iFppIi) return 129; + if (fun == &iFppIL) return 1; + if (fun == &iFppIp) return 1; + if (fun == &iFppCC) return 1; + if (fun == &iFppuw) return 193; + if (fun == &iFppui) return 193; + if (fun == &iFppuW) return 65; + if (fun == &iFppuu) return 193; + if (fun == &iFppuf) return 66; + if (fun == &iFppul) return 65; + if (fun == &iFppuL) return 65; + if (fun == &iFppup) return 65; + if (fun == &iFppUi) return 129; + if (fun == &iFppUU) return 1; + if (fun == &iFppUp) return 1; + if (fun == &iFppdi) return 66; + if (fun == &iFppdd) return 3; + if (fun == &iFppdp) return 2; + if (fun == &iFppli) return 129; + if (fun == &iFppll) return 1; + if (fun == &iFpplL) return 1; + if (fun == &iFpplp) return 1; + if (fun == &iFppLi) return 129; + if (fun == &iFppLu) return 129; + if (fun == &iFppLl) return 1; + if (fun == &iFppLL) return 1; + if (fun == &iFppLp) return 1; + if (fun == &iFpppi) return 129; + if (fun == &iFpppC) return 1; + if (fun == &iFpppu) return 129; + if (fun == &iFpppU) return 1; + if (fun == &iFpppd) return 2; + if (fun == &iFpppL) return 1; + if (fun == &iFpppp) return 1; + if (fun == &IFIIIu) return 129; + if (fun == &IFIUUu) return 129; + if (fun == &IFUIUI) return 1; + if (fun == &IFpIip) return 65; + if (fun == &IFpupI) return 33; + if (fun == &IFppii) return 193; + if (fun == &IFppip) return 65; + if (fun == &CFuuff) return 51; + if (fun == &CFpLLi) return 129; + if (fun == &CFppip) return 65; + if (fun == &uFiiii) return 241; + if (fun == &uFiiuu) return 241; + if (fun == &uFiipp) return 49; + if (fun == &uFifff) return 20; + if (fun == &uFippp) return 17; + if (fun == &uFuipi) return 177; + if (fun == &uFuuuu) return 241; + if (fun == &uFuupp) return 49; + if (fun == &uFupup) return 81; + if (fun == &uFuppU) return 17; + if (fun == &uFuppd) return 18; + if (fun == &uFuppp) return 17; + if (fun == &uFUiLL) return 33; + if (fun == &uFUCLp) return 1; + if (fun == &uFUWLp) return 1; + if (fun == &uFUuLp) return 33; + if (fun == &uFUULp) return 1; + if (fun == &uFULip) return 65; + if (fun == &uFULui) return 193; + if (fun == &uFULpL) return 1; + if (fun == &uFUpLL) return 1; + if (fun == &uFUpLp) return 1; + if (fun == &uFLpUp) return 1; + if (fun == &uFLppp) return 1; + if (fun == &uFpiii) return 225; + if (fun == &uFpiiu) return 225; + if (fun == &uFpiip) return 97; + if (fun == &uFpiup) return 97; + if (fun == &uFpipi) return 161; + if (fun == &uFpipu) return 161; + if (fun == &uFpipL) return 33; + if (fun == &uFpipp) return 33; + if (fun == &uFpCCC) return 1; + if (fun == &uFpuii) return 225; + if (fun == &uFpuui) return 225; + if (fun == &uFpuuu) return 225; + if (fun == &uFpuup) return 97; + if (fun == &uFpupi) return 161; + if (fun == &uFpupu) return 161; + if (fun == &uFpupL) return 33; + if (fun == &uFpupp) return 33; + if (fun == &uFpUuu) return 193; + if (fun == &uFpUuU) return 65; + if (fun == &uFpUUu) return 129; + if (fun == &uFpULu) return 129; + if (fun == &uFpULp) return 1; + if (fun == &uFpUpp) return 1; + if (fun == &uFplup) return 65; + if (fun == &uFpLUL) return 1; + if (fun == &uFpLpU) return 1; + if (fun == &uFpLpL) return 1; + if (fun == &uFpLpp) return 1; + if (fun == &uFppii) return 193; + if (fun == &uFppiu) return 193; + if (fun == &uFppiL) return 65; + if (fun == &uFppip) return 65; + if (fun == &uFppui) return 193; + if (fun == &uFppuu) return 193; + if (fun == &uFppuU) return 65; + if (fun == &uFppup) return 65; + if (fun == &uFppUL) return 1; + if (fun == &uFpplp) return 1; + if (fun == &uFppLi) return 129; + if (fun == &uFppLu) return 129; + if (fun == &uFppLL) return 1; + if (fun == &uFppLp) return 1; + if (fun == &uFpppi) return 129; + if (fun == &uFpppu) return 129; + if (fun == &uFpppU) return 1; + if (fun == &uFpppd) return 2; + if (fun == &uFpppL) return 1; + if (fun == &uFpppp) return 1; + if (fun == &UFppii) return 193; + if (fun == &UFppip) return 65; + if (fun == &UFppuu) return 193; + if (fun == &dFppdd) return -3; + if (fun == &dFpppp) return -1; + if (fun == &lFiiLu) return 177; + if (fun == &lFiipL) return 49; + if (fun == &lFipiI) return 81; + if (fun == &lFipil) return 81; + if (fun == &lFipLi) return 145; + if (fun == &lFipLI) return 17; + if (fun == &lFipLu) return 145; + if (fun == &lFipLl) return 17; + if (fun == &lFipLL) return 17; + if (fun == &lFipLp) return 17; + if (fun == &lFippL) return 17; + if (fun == &lFpili) return 161; + if (fun == &lFpilp) return 33; + if (fun == &lFpipL) return 33; + if (fun == &lFpuip) return 97; + if (fun == &lFplip) return 65; + if (fun == &lFplup) return 65; + if (fun == &lFplpi) return 129; + if (fun == &lFplpp) return 1; + if (fun == &lFpLpp) return 1; + if (fun == &lFppii) return 193; + if (fun == &lFppip) return 65; + if (fun == &lFpplp) return 1; + if (fun == &lFppLi) return 129; + if (fun == &lFppLp) return 1; + if (fun == &lFpppl) return 1; + if (fun == &lFpppL) return 1; + if (fun == &lFpppp) return 1; + if (fun == &LFipLL) return 17; + if (fun == &LFippL) return 17; + if (fun == &LFippp) return 17; + if (fun == &LFuipL) return 49; + if (fun == &LFpipl) return 33; + if (fun == &LFpipL) return 33; + if (fun == &LFpCii) return 193; + if (fun == &LFpupL) return 33; + if (fun == &LFplLL) return 1; + if (fun == &LFpLCL) return 1; + if (fun == &LFpLuu) return 193; + if (fun == &LFpLLp) return 1; + if (fun == &LFpLpi) return 129; + if (fun == &LFpLpL) return 1; + if (fun == &LFpLpp) return 1; + if (fun == &LFppii) return 193; + if (fun == &LFppip) return 65; + if (fun == &LFpplu) return 129; + if (fun == &LFpplL) return 1; + if (fun == &LFppLi) return 129; + if (fun == &LFppLu) return 129; + if (fun == &LFppLL) return 1; + if (fun == &LFppLp) return 1; + if (fun == &LFpppi) return 129; + if (fun == &LFpppu) return 129; + if (fun == &LFpppl) return 1; + if (fun == &LFpppL) return 1; + if (fun == &LFpppp) return 1; + if (fun == &pFiiii) return 241; + if (fun == &pFiiiu) return 241; + if (fun == &pFiiuu) return 241; + if (fun == &pFiiup) return 113; + if (fun == &pFiiLp) return 49; + if (fun == &pFiipi) return 177; + if (fun == &pFiipp) return 49; + if (fun == &pFifff) return 20; + if (fun == &pFiddu) return 51; + if (fun == &pFillu) return 145; + if (fun == &pFipip) return 81; + if (fun == &pFippi) return 145; + if (fun == &pFippu) return 145; + if (fun == &pFippl) return 17; + if (fun == &pFippL) return 17; + if (fun == &pFippp) return 17; + if (fun == &pFuuii) return 241; + if (fun == &pFuuip) return 113; + if (fun == &pFuuuu) return 241; + if (fun == &pFuddd) return 20; + if (fun == &pFudlL) return 18; + if (fun == &pFulli) return 145; + if (fun == &pFullu) return 145; + if (fun == &pFupii) return 209; + if (fun == &pFuppp) return 17; + if (fun == &pFffff) return 5; + if (fun == &pFdipp) return 18; + if (fun == &pFdddd) return 5; + if (fun == &pFlfff) return 4; + if (fun == &pFLiip) return 97; + if (fun == &pFLupp) return 33; + if (fun == &pFLLup) return 65; + if (fun == &pFLLLL) return 1; + if (fun == &pFLLpp) return 1; + if (fun == &pFLppp) return 1; + if (fun == &pFpiii) return 225; + if (fun == &pFpiiu) return 225; + if (fun == &pFpiiU) return 97; + if (fun == &pFpiip) return 97; + if (fun == &pFpiuu) return 225; + if (fun == &pFpiUL) return 33; + if (fun == &pFpiLi) return 161; + if (fun == &pFpiLu) return 161; + if (fun == &pFpiLL) return 33; + if (fun == &pFpipc) return 161; + if (fun == &pFpipi) return 161; + if (fun == &pFpipu) return 161; + if (fun == &pFpipd) return 34; + if (fun == &pFpipp) return 33; + if (fun == &pFpCip) return 65; + if (fun == &pFpCuu) return 193; + if (fun == &pFpWWW) return 1; + if (fun == &pFpuii) return 225; + if (fun == &pFpuip) return 97; + if (fun == &pFpuCC) return 33; + if (fun == &pFpuuu) return 225; + if (fun == &pFpuup) return 97; + if (fun == &pFpudd) return 35; + if (fun == &pFpuLL) return 33; + if (fun == &pFpupi) return 161; + if (fun == &pFpupu) return 161; + if (fun == &pFpupL) return 33; + if (fun == &pFpupp) return 33; + if (fun == &pFplil) return 65; + if (fun == &pFplip) return 65; + if (fun == &pFplpl) return 1; + if (fun == &pFplpp) return 1; + if (fun == &pFpLii) return 193; + if (fun == &pFpLip) return 65; + if (fun == &pFpLuu) return 193; + if (fun == &pFpLup) return 65; + if (fun == &pFpLLL) return 1; + if (fun == &pFpLLp) return 1; + if (fun == &pFpLpi) return 129; + if (fun == &pFpLpl) return 1; + if (fun == &pFpLpL) return 1; + if (fun == &pFpLpp) return 1; + if (fun == &pFppii) return 193; + if (fun == &pFppiu) return 193; + if (fun == &pFppiL) return 65; + if (fun == &pFppip) return 65; + if (fun == &pFppCp) return 1; + if (fun == &pFppWp) return 1; + if (fun == &pFppui) return 193; + if (fun == &pFppuu) return 193; + if (fun == &pFppup) return 65; + if (fun == &pFppdd) return 3; + if (fun == &pFppll) return 1; + if (fun == &pFpplp) return 1; + if (fun == &pFppLi) return 129; + if (fun == &pFppLu) return 129; + if (fun == &pFppLL) return 1; + if (fun == &pFppLp) return 1; + if (fun == &pFpppi) return 129; + if (fun == &pFpppu) return 129; + if (fun == &pFpppL) return 1; + if (fun == &pFpppp) return 1; + if (fun == &vFiiiii) return 497; + if (fun == &vFiiiiu) return 497; + if (fun == &vFiiipi) return 369; + if (fun == &vFiiuii) return 497; + if (fun == &vFiiuup) return 241; + if (fun == &vFiillu) return 305; + if (fun == &vFiilll) return 49; + if (fun == &vFiipll) return 49; + if (fun == &vFiIIII) return 17; + if (fun == &vFiuiip) return 241; + if (fun == &vFiuipi) return 369; + if (fun == &vFiuuuu) return 497; + if (fun == &vFiulpp) return 49; + if (fun == &vFiUUUU) return 17; + if (fun == &vFiffff) return 21; + if (fun == &vFidddd) return 21; + if (fun == &vFilill) return 81; + if (fun == &vFilipi) return 337; + if (fun == &vFilipl) return 81; + if (fun == &vFipipu) return 337; + if (fun == &vFipipp) return 81; + if (fun == &vFipupi) return 337; + if (fun == &vFucccc) return 497; + if (fun == &vFuwwww) return 497; + if (fun == &vFuiiii) return 497; + if (fun == &vFuiiiu) return 497; + if (fun == &vFuiiip) return 241; + if (fun == &vFuiiCp) return 113; + if (fun == &vFuiiup) return 241; + if (fun == &vFuiill) return 113; + if (fun == &vFuiIII) return 49; + if (fun == &vFuiuii) return 497; + if (fun == &vFuiuip) return 241; + if (fun == &vFuiuCi) return 369; + if (fun == &vFuiuCu) return 369; + if (fun == &vFuiuuu) return 497; + if (fun == &vFuiuup) return 241; + if (fun == &vFuiupi) return 369; + if (fun == &vFuiUUU) return 49; + if (fun == &vFuifff) return 52; + if (fun == &vFuiddd) return 52; + if (fun == &vFuipii) return 433; + if (fun == &vFuipip) return 177; + if (fun == &vFuipup) return 177; + if (fun == &vFuippp) return 49; + if (fun == &vFuIIII) return 17; + if (fun == &vFuCCCC) return 17; + if (fun == &vFuCuip) return 209; + if (fun == &vFuCuup) return 209; + if (fun == &vFuWWWW) return 17; + if (fun == &vFuuiii) return 497; + if (fun == &vFuuiip) return 241; + if (fun == &vFuuiui) return 497; + if (fun == &vFuuiuu) return 497; + if (fun == &vFuuiup) return 241; + if (fun == &vFuuifi) return 242; + if (fun == &vFuuipC) return 113; + if (fun == &vFuuipu) return 369; + if (fun == &vFuuipp) return 113; + if (fun == &vFuuuii) return 497; + if (fun == &vFuuuiu) return 497; + if (fun == &vFuuuil) return 241; + if (fun == &vFuuuip) return 241; + if (fun == &vFuuuui) return 497; + if (fun == &vFuuuuu) return 497; + if (fun == &vFuuuup) return 241; + if (fun == &vFuuuli) return 369; + if (fun == &vFuuull) return 113; + if (fun == &vFuulll) return 49; + if (fun == &vFuullp) return 49; + if (fun == &vFuupii) return 433; + if (fun == &vFuuppu) return 305; + if (fun == &vFuUUUU) return 17; + if (fun == &vFuffff) return 21; + if (fun == &vFudddd) return 21; + if (fun == &vFullpu) return 273; + if (fun == &vFupiii) return 465; + if (fun == &vFupupi) return 337; + if (fun == &vFupupp) return 81; + if (fun == &vFuplii) return 401; + if (fun == &vFuppip) return 145; + if (fun == &vFupppu) return 273; + if (fun == &vFupppp) return 17; + if (fun == &vFfffff) return 6; + if (fun == &vFddddp) return 5; + if (fun == &vFluipp) return 97; + if (fun == &vFlplpl) return 1; + if (fun == &vFLpppi) return 257; + if (fun == &vFLpppp) return 1; + if (fun == &vFpwwWW) return 97; + if (fun == &vFpiiii) return 481; + if (fun == &vFpiiiu) return 481; + if (fun == &vFpiiip) return 225; + if (fun == &vFpiiuu) return 481; + if (fun == &vFpiiup) return 225; + if (fun == &vFpiiff) return 99; + if (fun == &vFpiipp) return 97; + if (fun == &vFpiuuu) return 481; + if (fun == &vFpilpp) return 33; + if (fun == &vFpipii) return 417; + if (fun == &vFpipiu) return 417; + if (fun == &vFpippi) return 289; + if (fun == &vFpippp) return 33; + if (fun == &vFpuiii) return 481; + if (fun == &vFpuiil) return 225; + if (fun == &vFpuiip) return 225; + if (fun == &vFpuill) return 97; + if (fun == &vFpuipp) return 97; + if (fun == &vFpuuuu) return 481; + if (fun == &vFpuuup) return 225; + if (fun == &vFpuupp) return 97; + if (fun == &vFpuUpp) return 33; + if (fun == &vFpuddd) return 36; + if (fun == &vFpulul) return 161; + if (fun == &vFpulll) return 33; + if (fun == &vFpupiu) return 417; + if (fun == &vFpupup) return 161; + if (fun == &vFpupUu) return 289; + if (fun == &vFpuppp) return 33; + if (fun == &vFpUpUu) return 257; + if (fun == &vFpfffi) return 36; + if (fun == &vFpffff) return 5; + if (fun == &vFpdull) return 34; + if (fun == &vFpddii) return 99; + if (fun == &vFpdddd) return 5; + if (fun == &vFpddpp) return 3; + if (fun == &vFpliip) return 193; + if (fun == &vFpluul) return 193; + if (fun == &vFplplp) return 1; + if (fun == &vFpLiii) return 449; + if (fun == &vFpLiiL) return 193; + if (fun == &vFpLLLL) return 1; + if (fun == &vFpLLLp) return 1; + if (fun == &vFpLLpp) return 1; + if (fun == &vFpLpiL) return 129; + if (fun == &vFpLppi) return 257; + if (fun == &vFpLppp) return 1; + if (fun == &vFppiic) return 449; + if (fun == &vFppiii) return 449; + if (fun == &vFppiiu) return 449; + if (fun == &vFppiid) return 194; + if (fun == &vFppiiL) return 193; + if (fun == &vFppiip) return 193; + if (fun == &vFppiui) return 449; + if (fun == &vFppiup) return 193; + if (fun == &vFppiff) return 67; + if (fun == &vFppidd) return 67; + if (fun == &vFppipi) return 321; + if (fun == &vFppipu) return 321; + if (fun == &vFppipp) return 65; + if (fun == &vFppWui) return 385; + if (fun == &vFppuii) return 449; + if (fun == &vFppuui) return 449; + if (fun == &vFppuuu) return 449; + if (fun == &vFppuup) return 193; + if (fun == &vFppudd) return 67; + if (fun == &vFppupi) return 321; + if (fun == &vFppupu) return 321; + if (fun == &vFppupp) return 65; + if (fun == &vFppUuu) return 385; + if (fun == &vFppUUu) return 257; + if (fun == &vFppUUp) return 1; + if (fun == &vFppfff) return 4; + if (fun == &vFppddp) return 3; + if (fun == &vFpplll) return 1; + if (fun == &vFppLLp) return 1; + if (fun == &vFppLpL) return 1; + if (fun == &vFppLpp) return 1; + if (fun == &vFpppii) return 385; + if (fun == &vFpppip) return 129; + if (fun == &vFpppui) return 385; + if (fun == &vFpppuu) return 385; + if (fun == &vFpppup) return 129; + if (fun == &vFpppff) return 3; + if (fun == &vFpppfp) return 2; + if (fun == &vFpppdd) return 3; + if (fun == &vFpppdp) return 2; + if (fun == &vFppppi) return 257; + if (fun == &vFppppu) return 257; + if (fun == &vFppppL) return 1; + if (fun == &vFppppp) return 1; + if (fun == &iFiiiiW) return 241; + if (fun == &iFiiiip) return 241; + if (fun == &iFiiiui) return 497; + if (fun == &iFiiipu) return 369; + if (fun == &iFiiipL) return 113; + if (fun == &iFiiipp) return 113; + if (fun == &iFiiupp) return 113; + if (fun == &iFiipui) return 433; + if (fun == &iFiippu) return 305; + if (fun == &iFiippp) return 49; + if (fun == &iFiuuuu) return 497; + if (fun == &iFiuuuU) return 241; + if (fun == &iFiuuup) return 241; + if (fun == &iFiuUip) return 177; + if (fun == &iFiuppi) return 305; + if (fun == &iFillLL) return 17; + if (fun == &iFiLLpp) return 17; + if (fun == &iFipiii) return 465; + if (fun == &iFipiip) return 209; + if (fun == &iFipipi) return 337; + if (fun == &iFipipu) return 337; + if (fun == &iFipuip) return 209; + if (fun == &iFipuui) return 465; + if (fun == &iFipupL) return 81; + if (fun == &iFipLup) return 145; + if (fun == &iFippuu) return 401; + if (fun == &iFippLi) return 273; + if (fun == &iFippLp) return 17; + if (fun == &iFipppi) return 273; + if (fun == &iFipppp) return 17; + if (fun == &iFuiiii) return 497; + if (fun == &iFuiuup) return 241; + if (fun == &iFuuuuU) return 241; + if (fun == &iFuuuup) return 241; + if (fun == &iFuuupp) return 113; + if (fun == &iFuupid) return 178; + if (fun == &iFuupup) return 177; + if (fun == &iFuuppp) return 49; + if (fun == &iFupupp) return 81; + if (fun == &iFuppLp) return 17; + if (fun == &iFupppp) return 17; + if (fun == &iFLppip) return 129; + if (fun == &iFLpppp) return 1; + if (fun == &iFpciUU) return 97; + if (fun == &iFpwwww) return 481; + if (fun == &iFpwppp) return 33; + if (fun == &iFpiiii) return 481; + if (fun == &iFpiiiu) return 481; + if (fun == &iFpiiiL) return 225; + if (fun == &iFpiiip) return 225; + if (fun == &iFpiiui) return 481; + if (fun == &iFpiiuu) return 481; + if (fun == &iFpiipi) return 353; + if (fun == &iFpiipp) return 97; + if (fun == &iFpiuwp) return 225; + if (fun == &iFpiuuu) return 481; + if (fun == &iFpiuLi) return 353; + if (fun == &iFpiupi) return 353; + if (fun == &iFpiupp) return 97; + if (fun == &iFpiUpi) return 289; + if (fun == &iFpiLip) return 161; + if (fun == &iFpiLuu) return 417; + if (fun == &iFpipii) return 417; + if (fun == &iFpipiu) return 417; + if (fun == &iFpipiL) return 161; + if (fun == &iFpipip) return 161; + if (fun == &iFpiplp) return 33; + if (fun == &iFpippi) return 289; + if (fun == &iFpippW) return 33; + if (fun == &iFpippL) return 33; + if (fun == &iFpippp) return 33; + if (fun == &iFpIppp) return 1; + if (fun == &iFpCCCC) return 1; + if (fun == &iFpCCpu) return 257; + if (fun == &iFpCupp) return 65; + if (fun == &iFpCpip) return 129; + if (fun == &iFpCpCp) return 1; + if (fun == &iFpuiip) return 225; + if (fun == &iFpuill) return 97; + if (fun == &iFpuipu) return 353; + if (fun == &iFpuipp) return 97; + if (fun == &iFpuuip) return 225; + if (fun == &iFpuuuW) return 225; + if (fun == &iFpuuuu) return 481; + if (fun == &iFpuuup) return 225; + if (fun == &iFpuuLL) return 97; + if (fun == &iFpuuLp) return 97; + if (fun == &iFpuupi) return 353; + if (fun == &iFpuupp) return 97; + if (fun == &iFpuUpU) return 33; + if (fun == &iFpulup) return 161; + if (fun == &iFpulpp) return 33; + if (fun == &iFpuLup) return 161; + if (fun == &iFpuLpL) return 33; + if (fun == &iFpuLpp) return 33; + if (fun == &iFpupui) return 417; + if (fun == &iFpupuu) return 417; + if (fun == &iFpupuU) return 161; + if (fun == &iFpupup) return 161; + if (fun == &iFpupLu) return 289; + if (fun == &iFpupLp) return 33; + if (fun == &iFpuppi) return 289; + if (fun == &iFpuppu) return 289; + if (fun == &iFpuppL) return 33; + if (fun == &iFpuppp) return 33; + if (fun == &iFpUiip) return 193; + if (fun == &iFpffff) return 5; + if (fun == &iFpffpp) return 3; + if (fun == &iFpdddd) return 5; + if (fun == &iFplupp) return 65; + if (fun == &iFplluu) return 385; + if (fun == &iFpLiup) return 193; + if (fun == &iFpLilp) return 65; + if (fun == &iFpLiLi) return 321; + if (fun == &iFpLipi) return 321; + if (fun == &iFpLipC) return 65; + if (fun == &iFpLuLi) return 321; + if (fun == &iFpLlpp) return 1; + if (fun == &iFpLLii) return 385; + if (fun == &iFpLLup) return 129; + if (fun == &iFpLpii) return 385; + if (fun == &iFpLpiL) return 129; + if (fun == &iFpLpuL) return 129; + if (fun == &iFpLpup) return 129; + if (fun == &iFpLpLi) return 257; + if (fun == &iFpLpLp) return 1; + if (fun == &iFpLppi) return 257; + if (fun == &iFpLppL) return 1; + if (fun == &iFpLppp) return 1; + if (fun == &iFppiii) return 449; + if (fun == &iFppiiu) return 449; + if (fun == &iFppiif) return 194; + if (fun == &iFppiiL) return 193; + if (fun == &iFppiip) return 193; + if (fun == &iFppiuu) return 449; + if (fun == &iFppiup) return 193; + if (fun == &iFppiLi) return 321; + if (fun == &iFppipi) return 321; + if (fun == &iFppipu) return 321; + if (fun == &iFppipl) return 65; + if (fun == &iFppipp) return 65; + if (fun == &iFppIII) return 1; + if (fun == &iFppWpp) return 1; + if (fun == &iFppuwp) return 193; + if (fun == &iFppuii) return 449; + if (fun == &iFppuip) return 193; + if (fun == &iFppuuu) return 449; + if (fun == &iFppuuf) return 194; + if (fun == &iFppuup) return 193; + if (fun == &iFppuLL) return 65; + if (fun == &iFppuLp) return 65; + if (fun == &iFppupi) return 321; + if (fun == &iFppupu) return 321; + if (fun == &iFppupl) return 65; + if (fun == &iFppupp) return 65; + if (fun == &iFppUup) return 129; + if (fun == &iFppUpp) return 1; + if (fun == &iFpplii) return 385; + if (fun == &iFppllp) return 1; + if (fun == &iFpplpp) return 1; + if (fun == &iFppLii) return 385; + if (fun == &iFppLiL) return 129; + if (fun == &iFppLup) return 129; + if (fun == &iFppLLi) return 257; + if (fun == &iFppLpi) return 257; + if (fun == &iFppLpL) return 1; + if (fun == &iFppLpp) return 1; + if (fun == &iFpppii) return 385; + if (fun == &iFpppiu) return 385; + if (fun == &iFpppip) return 129; + if (fun == &iFpppui) return 385; + if (fun == &iFpppuu) return 385; + if (fun == &iFpppup) return 129; + if (fun == &iFpppUi) return 257; + if (fun == &iFpppfp) return 2; + if (fun == &iFpppli) return 257; + if (fun == &iFpppLi) return 257; + if (fun == &iFpppLu) return 257; + if (fun == &iFpppLp) return 1; + if (fun == &iFppppi) return 257; + if (fun == &iFppppu) return 257; + if (fun == &iFppppd) return 2; + if (fun == &iFppppl) return 1; + if (fun == &iFppppL) return 1; + if (fun == &iFppppp) return 1; + if (fun == &IFpLIII) return 1; + if (fun == &IFppIII) return 1; + if (fun == &uFiuuuu) return 497; + if (fun == &uFiuppi) return 305; + if (fun == &uFipupp) return 81; + if (fun == &uFuiiii) return 497; + if (fun == &uFupLpp) return 17; + if (fun == &uFULCLL) return 1; + if (fun == &uFULWLL) return 1; + if (fun == &uFULuLL) return 65; + if (fun == &uFULULU) return 1; + if (fun == &uFULLUU) return 1; + if (fun == &uFUpUpL) return 1; + if (fun == &uFLpppL) return 1; + if (fun == &uFpiipp) return 97; + if (fun == &uFpCCCC) return 1; + if (fun == &uFpWuip) return 193; + if (fun == &uFpuuui) return 481; + if (fun == &uFpuuuW) return 225; + if (fun == &uFpuuuu) return 481; + if (fun == &uFpuuup) return 225; + if (fun == &uFpuupu) return 353; + if (fun == &uFpuupp) return 97; + if (fun == &uFpupuu) return 417; + if (fun == &uFpupLp) return 33; + if (fun == &uFpuppp) return 33; + if (fun == &uFpULuU) return 129; + if (fun == &uFpUppp) return 1; + if (fun == &uFpLuUL) return 65; + if (fun == &uFpLLUU) return 1; + if (fun == &uFpLpLL) return 1; + if (fun == &uFpLpLp) return 1; + if (fun == &uFppiip) return 193; + if (fun == &uFppiui) return 449; + if (fun == &uFppiUp) return 65; + if (fun == &uFppiLu) return 321; + if (fun == &uFppipp) return 65; + if (fun == &uFppCCC) return 1; + if (fun == &uFppuup) return 193; + if (fun == &uFppupp) return 65; + if (fun == &uFpplip) return 129; + if (fun == &uFpplpp) return 1; + if (fun == &uFppLLu) return 257; + if (fun == &uFppLLp) return 1; + if (fun == &uFppLpu) return 257; + if (fun == &uFppLpL) return 1; + if (fun == &uFppLpp) return 1; + if (fun == &uFpppip) return 129; + if (fun == &uFpppuu) return 385; + if (fun == &uFpppup) return 129; + if (fun == &uFpppLu) return 257; + if (fun == &uFpppLU) return 1; + if (fun == &uFpppLp) return 1; + if (fun == &uFppppu) return 257; + if (fun == &uFppppL) return 1; + if (fun == &uFppppp) return 1; + if (fun == &UFuiCiu) return 433; + if (fun == &fFlplpl) return -1; + if (fun == &fFppppL) return -1; + if (fun == &dFlplpl) return -1; + if (fun == &dFppddd) return -4; + if (fun == &dFppppL) return -1; + if (fun == &lFipiIi) return 337; + if (fun == &lFipili) return 337; + if (fun == &lFipLli) return 273; + if (fun == &lFipLlL) return 17; + if (fun == &lFipLLi) return 273; + if (fun == &lFipLpp) return 17; + if (fun == &lFpuipC) return 97; + if (fun == &lFpuuLL) return 97; + if (fun == &lFppupp) return 65; + if (fun == &lFpplLp) return 1; + if (fun == &lFpplpl) return 1; + if (fun == &lFppLpL) return 1; + if (fun == &lFppLpp) return 1; + if (fun == &LFuuuuu) return 497; + if (fun == &LFLpppl) return 1; + if (fun == &LFpuipp) return 97; + if (fun == &LFpuupi) return 353; + if (fun == &LFplplL) return 1; + if (fun == &LFplplp) return 1; + if (fun == &LFpLuuu) return 449; + if (fun == &LFpLLLp) return 1; + if (fun == &LFpLpuu) return 385; + if (fun == &LFpLpLi) return 257; + if (fun == &LFpLpLp) return 1; + if (fun == &LFpLppu) return 257; + if (fun == &LFpLppL) return 1; + if (fun == &LFpLppp) return 1; + if (fun == &LFppuup) return 193; + if (fun == &LFpplLp) return 1; + if (fun == &LFpplpl) return 1; + if (fun == &LFppLuu) return 385; + if (fun == &LFppLLp) return 1; + if (fun == &LFppLpL) return 1; + if (fun == &LFpppii) return 385; + if (fun == &LFppplL) return 1; + if (fun == &LFppplp) return 1; + if (fun == &LFppppi) return 257; + if (fun == &LFppppp) return 1; + if (fun == &pFiiupi) return 369; + if (fun == &pFiiupL) return 113; + if (fun == &pFipipL) return 81; + if (fun == &pFipipp) return 81; + if (fun == &pFuiiii) return 497; + if (fun == &pFuiiiu) return 497; + if (fun == &pFuiupp) return 113; + if (fun == &pFuuiip) return 241; + if (fun == &pFuuupu) return 369; + if (fun == &pFuupuu) return 433; + if (fun == &pFudddp) return 20; + if (fun == &pFuLdii) return 210; + if (fun == &pFupLpl) return 17; + if (fun == &pFupLpL) return 17; + if (fun == &pFddddu) return 21; + if (fun == &pFLuppp) return 33; + if (fun == &pFLLLiu) return 385; + if (fun == &pFLpppi) return 257; + if (fun == &pFpiiii) return 481; + if (fun == &pFpiiip) return 225; + if (fun == &pFpiiuu) return 481; + if (fun == &pFpiipi) return 353; + if (fun == &pFpiipp) return 97; + if (fun == &pFpiCCC) return 33; + if (fun == &pFpiuuu) return 481; + if (fun == &pFpiupp) return 97; + if (fun == &pFpiLip) return 161; + if (fun == &pFpipii) return 417; + if (fun == &pFpipiL) return 161; + if (fun == &pFpipip) return 161; + if (fun == &pFpipup) return 161; + if (fun == &pFpippi) return 289; + if (fun == &pFpippp) return 33; + if (fun == &pFpCiuu) return 449; + if (fun == &pFpuiii) return 481; + if (fun == &pFpuiip) return 225; + if (fun == &pFpuuii) return 481; + if (fun == &pFpuuip) return 225; + if (fun == &pFpuuuu) return 481; + if (fun == &pFpuuup) return 225; + if (fun == &pFpuupL) return 97; + if (fun == &pFpuupp) return 97; + if (fun == &pFpuLpp) return 33; + if (fun == &pFpupuu) return 417; + if (fun == &pFpuppu) return 289; + if (fun == &pFpuppp) return 33; + if (fun == &pFpfffi) return 36; + if (fun == &pFpdddd) return 5; + if (fun == &pFplppp) return 1; + if (fun == &pFpLiii) return 449; + if (fun == &pFpLipp) return 65; + if (fun == &pFpLLip) return 129; + if (fun == &pFpLLLp) return 1; + if (fun == &pFpLpii) return 385; + if (fun == &pFpLpip) return 129; + if (fun == &pFpLpuu) return 385; + if (fun == &pFpLpup) return 129; + if (fun == &pFpLppp) return 1; + if (fun == &pFppiii) return 449; + if (fun == &pFppiiu) return 449; + if (fun == &pFppiip) return 193; + if (fun == &pFppiup) return 193; + if (fun == &pFppiLp) return 65; + if (fun == &pFppipi) return 321; + if (fun == &pFppipp) return 65; + if (fun == &pFppCip) return 129; + if (fun == &pFppWpp) return 1; + if (fun == &pFppuip) return 193; + if (fun == &pFppuuu) return 449; + if (fun == &pFppuup) return 193; + if (fun == &pFppuLi) return 321; + if (fun == &pFppupu) return 321; + if (fun == &pFppupp) return 65; + if (fun == &pFppddu) return 67; + if (fun == &pFppLui) return 385; + if (fun == &pFppLuu) return 385; + if (fun == &pFppLLi) return 257; + if (fun == &pFppLpp) return 1; + if (fun == &pFpppii) return 385; + if (fun == &pFpppip) return 129; + if (fun == &pFpppui) return 385; + if (fun == &pFpppup) return 129; + if (fun == &pFpppli) return 257; + if (fun == &pFpppLi) return 257; + if (fun == &pFppppi) return 257; + if (fun == &pFppppu) return 257; + if (fun == &pFppppL) return 1; + if (fun == &pFppppp) return 1; + if (fun == &vFiiiiii) return 1009; + if (fun == &vFiiiuil) return 497; + if (fun == &vFiiilpi) return 625; + if (fun == &vFiiuilp) return 241; + if (fun == &vFiffiff) return 53; + if (fun == &vFiddidd) return 53; + if (fun == &vFilipli) return 593; + if (fun == &vFiliplu) return 593; + if (fun == &vFipiplp) return 81; + if (fun == &vFCCCCff) return 3; + if (fun == &vFuiiiii) return 1009; + if (fun == &vFuiiiip) return 497; + if (fun == &vFuiiuii) return 1009; + if (fun == &vFuiiuup) return 497; + if (fun == &vFuiIIII) return 49; + if (fun == &vFuiuiii) return 1009; + if (fun == &vFuiuiiC) return 497; + if (fun == &vFuiuiil) return 497; + if (fun == &vFuiuiip) return 497; + if (fun == &vFuiuiuu) return 1009; + if (fun == &vFuiuiuU) return 497; + if (fun == &vFuiuCip) return 369; + if (fun == &vFuiuuip) return 497; + if (fun == &vFuiuuuu) return 1009; + if (fun == &vFuiupii) return 881; + if (fun == &vFuiupiu) return 881; + if (fun == &vFuiUUUU) return 49; + if (fun == &vFuiffff) return 53; + if (fun == &vFuidddd) return 53; + if (fun == &vFuipiup) return 433; + if (fun == &vFuCuuip) return 465; + if (fun == &vFuuiiii) return 1009; + if (fun == &vFuuiuii) return 1009; + if (fun == &vFuuiuil) return 497; + if (fun == &vFuuiuip) return 497; + if (fun == &vFuuiuCu) return 753; + if (fun == &vFuuiuup) return 497; + if (fun == &vFuuippp) return 113; + if (fun == &vFuuuiii) return 1009; + if (fun == &vFuuuiup) return 497; + if (fun == &vFuuuipi) return 753; + if (fun == &vFuuuipC) return 241; + if (fun == &vFuuuipp) return 241; + if (fun == &vFuuuuii) return 1009; + if (fun == &vFuuuuip) return 497; + if (fun == &vFuuuuuu) return 1009; + if (fun == &vFuuuull) return 241; + if (fun == &vFuuuppi) return 625; + if (fun == &vFuuuppp) return 113; + if (fun == &vFuuffff) return 53; + if (fun == &vFuudddd) return 53; + if (fun == &vFuupiii) return 945; + if (fun == &vFuupupp) return 177; + if (fun == &vFuuplii) return 817; + if (fun == &vFuffiip) return 115; + if (fun == &vFufffff) return 22; + if (fun == &vFuddiip) return 115; + if (fun == &vFulluUC) return 145; + if (fun == &vFupiiii) return 977; + if (fun == &vFupupip) return 337; + if (fun == &vFuppppu) return 529; + if (fun == &vFuppppp) return 17; + if (fun == &vFUUpppp) return 1; + if (fun == &vFffffff) return 7; + if (fun == &vFdddddd) return 7; + if (fun == &vFdddppp) return 4; + if (fun == &vFlfplpl) return 2; + if (fun == &vFldplpl) return 2; + if (fun == &vFlplplp) return 1; + if (fun == &vFlpplpl) return 1; + if (fun == &vFpwwllc) return 609; + if (fun == &vFpiiiii) return 993; + if (fun == &vFpiiipp) return 225; + if (fun == &vFpiiuuu) return 993; + if (fun == &vFpiilli) return 609; + if (fun == &vFpiippi) return 609; + if (fun == &vFpiippp) return 97; + if (fun == &vFpiLppi) return 545; + if (fun == &vFpipiii) return 929; + if (fun == &vFpipipp) return 161; + if (fun == &vFpipppp) return 33; + if (fun == &vFpuiiii) return 993; + if (fun == &vFpuiiiu) return 993; + if (fun == &vFpuiipp) return 225; + if (fun == &vFpuuuiu) return 993; + if (fun == &vFpuuuuu) return 993; + if (fun == &vFpuuuup) return 481; + if (fun == &vFpuuupp) return 225; + if (fun == &vFpuupuu) return 865; + if (fun == &vFpuuppp) return 97; + if (fun == &vFpudddd) return 37; + if (fun == &vFpuLuuu) return 929; + if (fun == &vFpupuuu) return 929; + if (fun == &vFpupuup) return 417; + if (fun == &vFpupupu) return 673; + if (fun == &vFpuppuu) return 801; + if (fun == &vFpupppp) return 33; + if (fun == &vFpdddii) return 100; + if (fun == &vFpddddd) return 6; + if (fun == &vFpddddp) return 5; + if (fun == &vFpLiiii) return 961; + if (fun == &vFpLiiiL) return 449; + if (fun == &vFpLiipi) return 705; + if (fun == &vFpLLLLu) return 513; + if (fun == &vFpLpLLL) return 1; + if (fun == &vFpLpppi) return 513; + if (fun == &vFppiiii) return 961; + if (fun == &vFppiiiu) return 961; + if (fun == &vFppiiuu) return 961; + if (fun == &vFppiipi) return 705; + if (fun == &vFppiipp) return 193; + if (fun == &vFppilpp) return 65; + if (fun == &vFppipLp) return 65; + if (fun == &vFppippi) return 577; + if (fun == &vFppippp) return 65; + if (fun == &vFppCCCC) return 1; + if (fun == &vFppuiii) return 961; + if (fun == &vFppuiiu) return 961; + if (fun == &vFppuiip) return 449; + if (fun == &vFppuuuu) return 961; + if (fun == &vFppuuup) return 449; + if (fun == &vFppuUUU) return 65; + if (fun == &vFppupii) return 833; + if (fun == &vFppupup) return 321; + if (fun == &vFppuppp) return 65; + if (fun == &vFppffff) return 5; + if (fun == &vFppdidd) return 68; + if (fun == &vFppdddd) return 5; + if (fun == &vFpplplp) return 1; + if (fun == &vFpplppi) return 513; + if (fun == &vFpplppp) return 1; + if (fun == &vFppLppi) return 513; + if (fun == &vFppLppp) return 1; + if (fun == &vFpppiii) return 897; + if (fun == &vFpppiip) return 385; + if (fun == &vFpppiui) return 897; + if (fun == &vFpppiff) return 131; + if (fun == &vFpppipi) return 641; + if (fun == &vFpppipu) return 641; + if (fun == &vFpppipp) return 129; + if (fun == &vFpppuii) return 897; + if (fun == &vFpppuip) return 385; + if (fun == &vFpppuuu) return 897; + if (fun == &vFpppuup) return 385; + if (fun == &vFpppLpp) return 1; + if (fun == &vFppppii) return 769; + if (fun == &vFpppppi) return 513; + if (fun == &vFpppppu) return 513; + if (fun == &vFpppppU) return 1; + if (fun == &vFpppppL) return 1; + if (fun == &vFpppppp) return 1; + if (fun == &cFppLppi) return 513; + if (fun == &iFiiiipp) return 241; + if (fun == &iFiiiuwp) return 497; + if (fun == &iFiippiu) return 817; + if (fun == &iFiWiipi) return 721; + if (fun == &iFiuuuup) return 497; + if (fun == &iFiuuupu) return 753; + if (fun == &iFiuuUpU) return 113; + if (fun == &iFiuuppp) return 113; + if (fun == &iFiuUuUu) return 689; + if (fun == &iFiLpppi) return 529; + if (fun == &iFipipip) return 337; + if (fun == &iFipippp) return 81; + if (fun == &iFipuIup) return 337; + if (fun == &iFipupup) return 337; + if (fun == &iFipuppp) return 81; + if (fun == &iFipppLp) return 17; + if (fun == &iFippppp) return 17; + if (fun == &iFuiiuup) return 497; + if (fun == &iFuiifip) return 242; + if (fun == &iFuuIiip) return 433; + if (fun == &iFuuuuip) return 497; + if (fun == &iFuuuuup) return 497; + if (fun == &iFuupppp) return 49; + if (fun == &iFupupLp) return 81; + if (fun == &iFupuppp) return 81; + if (fun == &iFupLpLp) return 17; + if (fun == &iFuppppp) return 17; + if (fun == &iFdipppL) return 18; + if (fun == &iFllllpp) return 1; + if (fun == &iFlpippp) return 65; + if (fun == &iFLpppii) return 769; + if (fun == &iFpiiiii) return 993; + if (fun == &iFpiiiiu) return 993; + if (fun == &iFpiiiip) return 481; + if (fun == &iFpiiipp) return 225; + if (fun == &iFpiiuii) return 993; + if (fun == &iFpiiuui) return 993; + if (fun == &iFpiiupp) return 225; + if (fun == &iFpiiUpp) return 97; + if (fun == &iFpiiLip) return 353; + if (fun == &iFpiipcc) return 865; + if (fun == &iFpiipii) return 865; + if (fun == &iFpiipip) return 353; + if (fun == &iFpiippp) return 97; + if (fun == &iFpiIIIi) return 545; + if (fun == &iFpiCCpu) return 545; + if (fun == &iFpiuuup) return 481; + if (fun == &iFpiuupp) return 225; + if (fun == &iFpiupip) return 353; + if (fun == &iFpipipi) return 673; + if (fun == &iFpipipp) return 161; + if (fun == &iFpipupp) return 161; + if (fun == &iFpipLpp) return 33; + if (fun == &iFpippip) return 289; + if (fun == &iFpippup) return 289; + if (fun == &iFpipppu) return 545; + if (fun == &iFpipppp) return 33; + if (fun == &iFpCiipp) return 193; + if (fun == &iFpCpipu) return 641; + if (fun == &iFpWipip) return 321; + if (fun == &iFpWCupp) return 129; + if (fun == &iFpWpppp) return 1; + if (fun == &iFpuiCpp) return 97; + if (fun == &iFpuiLpp) return 97; + if (fun == &iFpuippp) return 97; + if (fun == &iFpuuuii) return 993; + if (fun == &iFpuuuuu) return 993; + if (fun == &iFpuuuup) return 481; + if (fun == &iFpuuupu) return 737; + if (fun == &iFpuuupp) return 225; + if (fun == &iFpuuLpp) return 97; + if (fun == &iFpuupii) return 865; + if (fun == &iFpuupuu) return 865; + if (fun == &iFpuuppu) return 609; + if (fun == &iFpuuppp) return 97; + if (fun == &iFpuLuLu) return 673; + if (fun == &iFpuLLpp) return 33; + if (fun == &iFpupupi) return 673; + if (fun == &iFpupupp) return 161; + if (fun == &iFpupLpL) return 33; + if (fun == &iFpupLpp) return 33; + if (fun == &iFpupppu) return 545; + if (fun == &iFpupppp) return 33; + if (fun == &iFpdpipp) return 66; + if (fun == &iFpLiiiL) return 449; + if (fun == &iFpLiiip) return 449; + if (fun == &iFpLiiuu) return 961; + if (fun == &iFpLipLu) return 577; + if (fun == &iFpLIppp) return 1; + if (fun == &iFpLuipp) return 193; + if (fun == &iFpLuupp) return 193; + if (fun == &iFpLupip) return 321; + if (fun == &iFpLuppp) return 65; + if (fun == &iFpLLLLu) return 513; + if (fun == &iFpLLLLL) return 1; + if (fun == &iFpLLLLp) return 1; + if (fun == &iFpLLppp) return 1; + if (fun == &iFpLpipi) return 641; + if (fun == &iFpLpLui) return 769; + if (fun == &iFpLpLpp) return 1; + if (fun == &iFpLppii) return 769; + if (fun == &iFpLpppL) return 1; + if (fun == &iFpLpppp) return 1; + if (fun == &iFppiiii) return 961; + if (fun == &iFppiiip) return 449; + if (fun == &iFppiipi) return 705; + if (fun == &iFppiipL) return 193; + if (fun == &iFppiipp) return 193; + if (fun == &iFppiuii) return 961; + if (fun == &iFppiupp) return 193; + if (fun == &iFppilpp) return 65; + if (fun == &iFppipii) return 833; + if (fun == &iFppipiL) return 321; + if (fun == &iFppipip) return 321; + if (fun == &iFppippi) return 577; + if (fun == &iFppippu) return 577; + if (fun == &iFppippp) return 65; + if (fun == &iFppILlL) return 1; + if (fun == &iFppIppp) return 1; + if (fun == &iFppCupp) return 129; + if (fun == &iFppuiii) return 961; + if (fun == &iFppuipp) return 193; + if (fun == &iFppuIII) return 65; + if (fun == &iFppuuLp) return 193; + if (fun == &iFppuupL) return 193; + if (fun == &iFppuupp) return 193; + if (fun == &iFppufff) return 68; + if (fun == &iFppulup) return 321; + if (fun == &iFppulll) return 65; + if (fun == &iFppuLpp) return 65; + if (fun == &iFppupip) return 321; + if (fun == &iFppupui) return 833; + if (fun == &iFppupul) return 321; + if (fun == &iFppuppu) return 577; + if (fun == &iFppuppp) return 65; + if (fun == &iFppUUup) return 257; + if (fun == &iFppUUpp) return 1; + if (fun == &iFppUppp) return 1; + if (fun == &iFppfipp) return 66; + if (fun == &iFppdidd) return 68; + if (fun == &iFpplupp) return 129; + if (fun == &iFpplppi) return 513; + if (fun == &iFppLiWL) return 129; + if (fun == &iFppLipp) return 129; + if (fun == &iFppLupp) return 129; + if (fun == &iFppLLiL) return 257; + if (fun == &iFppLLup) return 257; + if (fun == &iFppLLpp) return 1; + if (fun == &iFppLpLp) return 1; + if (fun == &iFppLppp) return 1; + if (fun == &iFpppiup) return 385; + if (fun == &iFpppipi) return 641; + if (fun == &iFpppipu) return 641; + if (fun == &iFpppipp) return 129; + if (fun == &iFpppuii) return 897; + if (fun == &iFpppuip) return 385; + if (fun == &iFpppuuu) return 897; + if (fun == &iFpppuup) return 385; + if (fun == &iFpppuLp) return 129; + if (fun == &iFpppupu) return 641; + if (fun == &iFpppupp) return 129; + if (fun == &iFppplLp) return 1; + if (fun == &iFpppLip) return 257; + if (fun == &iFpppLpi) return 513; + if (fun == &iFpppLpp) return 1; + if (fun == &iFppppiu) return 769; + if (fun == &iFppppip) return 257; + if (fun == &iFppppui) return 769; + if (fun == &iFppppuu) return 769; + if (fun == &iFppppup) return 257; + if (fun == &iFppppLp) return 1; + if (fun == &iFpppppi) return 513; + if (fun == &iFpppppu) return 513; + if (fun == &iFpppppL) return 1; + if (fun == &iFpppppp) return 1; + if (fun == &IFppuuuW) return 449; + if (fun == &uFipuppp) return 81; + if (fun == &uFuuuuuu) return 1009; + if (fun == &uFupuufp) return 210; + if (fun == &uFuppppp) return 17; + if (fun == &uFULCLLp) return 1; + if (fun == &uFULWLLp) return 1; + if (fun == &uFULuLLp) return 65; + if (fun == &uFULULLU) return 1; + if (fun == &uFUpUpLp) return 1; + if (fun == &uFpiippp) return 97; + if (fun == &uFpiuppu) return 609; + if (fun == &uFpWuipp) return 193; + if (fun == &uFpWuuCp) return 193; + if (fun == &uFpuippp) return 97; + if (fun == &uFpuuuup) return 481; + if (fun == &uFpuuupp) return 225; + if (fun == &uFpuuppp) return 97; + if (fun == &uFpuUppp) return 33; + if (fun == &uFpupuup) return 417; + if (fun == &uFpupupu) return 673; + if (fun == &uFpupupp) return 161; + if (fun == &uFpupppu) return 545; + if (fun == &uFpupppp) return 33; + if (fun == &uFppiiii) return 961; + if (fun == &uFppiuup) return 449; + if (fun == &uFppCCCC) return 1; + if (fun == &uFppuuup) return 449; + if (fun == &uFppuupu) return 705; + if (fun == &uFppLpLp) return 1; + if (fun == &uFppLppL) return 1; + if (fun == &uFpppupp) return 129; + if (fun == &uFpppLUL) return 1; + if (fun == &uFpppLLu) return 513; + if (fun == &uFpppLpp) return 1; + if (fun == &uFppppuu) return 769; + if (fun == &uFppppLi) return 513; + if (fun == &uFppppLu) return 513; + if (fun == &uFppppLp) return 1; + if (fun == &uFpppppi) return 513; + if (fun == &uFpppppp) return 1; + if (fun == &fFlfplpl) return -2; + if (fun == &fFpppppL) return -1; + if (fun == &dFpppppL) return -1; + if (fun == &lFipipLu) return 593; + if (fun == &lFipLipu) return 657; + if (fun == &lFipLipp) return 145; + if (fun == &lFipLpLL) return 17; + if (fun == &lFpipill) return 161; + if (fun == &lFpuuLLp) return 97; + if (fun == &lFpluuic) return 961; + if (fun == &lFppuppL) return 65; + if (fun == &lFppLipp) return 129; + if (fun == &lFpppLpp) return 1; + if (fun == &LFpipipi) return 673; + if (fun == &LFplplpl) return 1; + if (fun == &LFpLippp) return 65; + if (fun == &LFpLLLLL) return 1; + if (fun == &LFppipLp) return 65; + if (fun == &LFpplplp) return 1; + if (fun == &LFppLLpL) return 1; + if (fun == &LFppLpLi) return 513; + if (fun == &LFppLpLp) return 1; + if (fun == &pFiiiiii) return 1009; + if (fun == &pFiiiiid) return 498; + if (fun == &pFipippp) return 81; + if (fun == &pFWCiWCi) return 577; + if (fun == &pFuCCCCp) return 17; + if (fun == &pFuuipip) return 369; + if (fun == &pFuuuiip) return 497; + if (fun == &pFuuuuii) return 1009; + if (fun == &pFuuuuuu) return 1009; + if (fun == &pFuuuuup) return 497; + if (fun == &pFuuppuu) return 817; + if (fun == &pFuppppp) return 17; + if (fun == &pFdddddd) return 7; + if (fun == &pFLppppp) return 1; + if (fun == &pFpiiiiu) return 993; + if (fun == &pFpiiiiU) return 481; + if (fun == &pFpiiipp) return 225; + if (fun == &pFpiiCCC) return 97; + if (fun == &pFpiiuuu) return 993; + if (fun == &pFpiipip) return 353; + if (fun == &pFpiippp) return 97; + if (fun == &pFpiuuup) return 481; + if (fun == &pFpidddd) return 37; + if (fun == &pFpiLLLL) return 33; + if (fun == &pFpipipL) return 161; + if (fun == &pFpipipp) return 161; + if (fun == &pFpipuii) return 929; + if (fun == &pFpippip) return 289; + if (fun == &pFpipppp) return 33; + if (fun == &pFpuuiip) return 481; + if (fun == &pFpuuuuu) return 993; + if (fun == &pFpuuuup) return 481; + if (fun == &pFpuuupu) return 737; + if (fun == &pFpupuui) return 929; + if (fun == &pFpupuuu) return 929; + if (fun == &pFpupuup) return 417; + if (fun == &pFpuppip) return 289; + if (fun == &pFpupppp) return 33; + if (fun == &pFplpppp) return 1; + if (fun == &pFpLuLpp) return 65; + if (fun == &pFpLuppp) return 65; + if (fun == &pFpLpLuu) return 769; + if (fun == &pFpLpLLi) return 513; + if (fun == &pFpLppii) return 769; + if (fun == &pFpLppip) return 257; + if (fun == &pFpLppup) return 257; + if (fun == &pFpLpppp) return 1; + if (fun == &pFppiiii) return 961; + if (fun == &pFppiiup) return 449; + if (fun == &pFppiipp) return 193; + if (fun == &pFppiIll) return 65; + if (fun == &pFppiCCC) return 65; + if (fun == &pFppiupp) return 193; + if (fun == &pFppilpp) return 65; + if (fun == &pFppiLll) return 65; + if (fun == &pFppipip) return 321; + if (fun == &pFppippi) return 577; + if (fun == &pFppippp) return 65; + if (fun == &pFppuuuu) return 961; + if (fun == &pFppuupp) return 193; + if (fun == &pFppuLli) return 577; + if (fun == &pFppupLi) return 577; + if (fun == &pFppuppp) return 65; + if (fun == &pFpplplp) return 1; + if (fun == &pFpplppp) return 1; + if (fun == &pFppLuui) return 897; + if (fun == &pFppLpuu) return 769; + if (fun == &pFpppiip) return 385; + if (fun == &pFpppupp) return 129; + if (fun == &pFpppLii) return 769; + if (fun == &pFpppLui) return 769; + if (fun == &pFppppii) return 769; + if (fun == &pFppppiL) return 257; + if (fun == &pFpppppi) return 513; + if (fun == &pFpppppu) return 513; + if (fun == &pFpppppp) return 1; + if (fun == &vFiiffffp) return 53; + if (fun == &vFCCCCfff) return 4; + if (fun == &vFuipffff) return 53; + if (fun == &vFuipdddd) return 53; + if (fun == &vFuuuffff) return 117; + if (fun == &vFuuudddd) return 117; + if (fun == &vFuuffiip) return 243; + if (fun == &vFuuddiip) return 243; + if (fun == &vFuulfplp) return 50; + if (fun == &vFuuldplp) return 50; + if (fun == &vFuffffff) return 23; + if (fun == &vFudddddd) return 23; + if (fun == &vFlfplfpl) return 3; + if (fun == &vFldpldpl) return 3; + if (fun == &vFlplplff) return 3; + if (fun == &vFlplpldd) return 3; + if (fun == &vFpfffppp) return 4; + if (fun == &vFpddiidd) return 101; + if (fun == &vFpdddddd) return 7; + if (fun == &vFppddddu) return 69; + if (fun == &vFppddpiu) return 387; + if (fun == &vFpppffff) return 5; + if (fun == &iFpiiifff) return 228; + if (fun == &iFpiiffff) return 101; + if (fun == &iFppppdpu) return 514; + if (fun == &pFifffppp) return 20; + if (fun == &pFudddduu) return 117; + if (fun == &pFfiiiiid) return 499; + if (fun == &pFduuulul) return 370; + if (fun == &pFpiiiiid) return 994; + if (fun == &pFpiuLdii) return 866; + if (fun == &pFpppfffi) return 132; + if (fun == &pFpppdddi) return 132; + if (fun == &vFuCCCCfff) return 20; + if (fun == &vFuuufffff) return 118; + if (fun == &vFffffffff) return 9; + if (fun == &vFpudddddd) return 39; + if (fun == &pFpudddduu) return 229; + if (fun == &vFuffffffff) return 25; + if (fun == &vFffCCCCfff) return 6; + if (fun == &vFppddddudd) return 71; + if (fun == &vFpppffffff) return 7; + if (fun == &iFdddpppppp) return 4; + if (fun == &iFpppfffffp) return 6; + if (fun == &vFuffiiffiip) return 501; + if (fun == &vFuddiiddiip) return 501; + if (fun == &vFppdddddddd) return 9; + if (fun == &iFpiLLdduudd) return 805; + if (fun == &iFpppfffffpf) return 7; + if (fun == &lFpLppdddddd) return 7; +#if defined(NOALIGN) + if (fun == &iFipipp) return 81; +#endif +#if !defined(STATICBUILD) + if (fun == &iFlip) return 33; + if (fun == &iFLLi) return 65; + if (fun == &iFLLii) return 193; + if (fun == &WFpLLu) return 129; + if (fun == &pFpLLi) return 129; + if (fun == &lFpLpdddddd) return 7; +#endif + return 0; +} #else int isSimpleWrapper(wrapper_t fun) { return 0;