| 4557 | } |
| 4558 | |
| 4559 | void OpDispatchBuilder::INTOp(OpcodeArgs) { |
| 4560 | IR::BreakDefinition Reason; |
| 4561 | bool SetRIPToNext = false; |
| 4562 | |
| 4563 | switch (Op->OP) { |
| 4564 | case 0xCD: { // INT imm8 |
| 4565 | uint8_t Literal = Op->Src[0].Data.Literal.Value; |
| 4566 | |
| 4567 | #ifndef _WIN32 |
| 4568 | constexpr uint8_t SYSCALL_LITERAL = 0x80; |
| 4569 | if (Literal == SYSCALL_LITERAL) { |
| 4570 | if (Is64BitMode) [[unlikely]] { |
| 4571 | LogMan::Msg::EFmt("[Unsupported] Trying to execute 32-bit syscall from a 64-bit process."); |
| 4572 | UnhandledOp(Op); |
| 4573 | return; |
| 4574 | } |
| 4575 | // Syscall on linux |
| 4576 | SyscallOp(Op, false); |
| 4577 | return; |
| 4578 | } |
| 4579 | #else |
| 4580 | constexpr uint8_t SYSCALL_LITERAL = 0x2E; |
| 4581 | if (Literal == SYSCALL_LITERAL) { |
| 4582 | // Can be used for both 64-bit and 32-bit syscalls on windows |
| 4583 | SyscallOp(Op, false); |
| 4584 | return; |
| 4585 | } |
| 4586 | #endif |
| 4587 | |
| 4588 | #ifdef _M_ARM_64EC |
| 4589 | // This is used when QueryPerformanceCounter is called on recent Windows versions, it causes CNTVCT to be written into RAX. |
| 4590 | constexpr uint8_t GET_CNTVCT_LITERAL = 0x81; |
| 4591 | if (Literal == GET_CNTVCT_LITERAL) { |
| 4592 | StoreGPRRegister(X86State::REG_RAX, _CycleCounter(false)); |
| 4593 | return; |
| 4594 | } |
| 4595 | #endif |
| 4596 | |
| 4597 | Reason.ErrorRegister = Literal << 3 | (0b010); |
| 4598 | Reason.Signal = Core::FAULT_SIGSEGV; |
| 4599 | // GP is raised when task-gate isn't setup to be valid |
| 4600 | Reason.TrapNumber = X86State::X86_TRAPNO_GP; |
| 4601 | Reason.si_code = 0x80; |
| 4602 | break; |
| 4603 | } |
| 4604 | case 0xCE: // INTO |
| 4605 | Reason.ErrorRegister = 0; |
| 4606 | Reason.Signal = Core::FAULT_SIGSEGV; |
| 4607 | Reason.TrapNumber = X86State::X86_TRAPNO_OF; |
| 4608 | Reason.si_code = 0x80; |
| 4609 | break; |
| 4610 | case 0xF1: // INT1 |
| 4611 | Reason.ErrorRegister = 0; |
| 4612 | Reason.Signal = Core::FAULT_SIGTRAP; |
| 4613 | Reason.TrapNumber = X86State::X86_TRAPNO_DB; |
| 4614 | Reason.si_code = 1; |
| 4615 | SetRIPToNext = true; |
| 4616 | break; |