Merge pull request #486 from FEX-Emu/skmp/abi-opts

Unsafe opts: --unsafe-local-flags, --unsafe-no-pf, --unsafe-no-tso
This commit is contained in:
Ryan Houdek authored and GitHub committed 2020-11-17 01:16:06 -08:00
commit 96472a9b59
12 files changed
+103 -34

No files matched your search

+12
View File
@@ -39,6 +39,12 @@ namespace FEXCore::Config {
case FEXCore::Config::CONFIG_SMC_CHECKS:
CTX->Config.SMCChecks = Config != 0;
break;
case FEXCore::Config::CONFIG_ABI_LOCAL_FLAGS:
CTX->Config.ABILocalFlags = Config != 0;
break;
case FEXCore::Config::CONFIG_ABI_NO_PF:
CTX->Config.ABINoPF = Config != 0;
break;
default: LogMan::Msg::A("Unknown configuration option");
}
}
@@ -92,6 +98,12 @@ namespace FEXCore::Config {
case FEXCore::Config::CONFIG_SMC_CHECKS:
return CTX->Config.SMCChecks;
break;
case FEXCore::Config::CONFIG_ABI_LOCAL_FLAGS:
return CTX->Config.ABILocalFlags;
break;
case FEXCore::Config::CONFIG_ABI_NO_PF:
return CTX->Config.ABINoPF;
break;
default: LogMan::Msg::A("Unknown configuration option");
}
+3
View File
@@ -62,8 +62,11 @@ namespace FEXCore::Context {
uint64_t EmulatedCPUCores{1};
bool TSOEnabled {true};
bool SMCChecks {false};
bool ABILocalFlags {false};
bool ABINoPF {false};
std::string DumpIR;
} Config;
FEXCore::Memory::MemMapper MemoryMapper;
@@ -488,6 +488,7 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) {
case IR::OP_DUMMY:
case IR::OP_BEGINBLOCK:
case IR::OP_ENDBLOCK:
case IR::OP_INVALIDATEFLAGS:
break;
case IR::OP_FENCE: {
auto Op = IROp->C<IR::IROp_Fence>();
@@ -126,6 +126,7 @@ void JITCore::RegisterMiscHandlers() {
REGISTER_OP(PRINT, Unhandled);
REGISTER_OP(GETROUNDINGMODE, GetRoundingMode);
REGISTER_OP(SETROUNDINGMODE, SetRoundingMode);
REGISTER_OP(INVALIDATEFLAGS, NoOp);
#undef REGISTER_OP
}
}
@@ -142,6 +142,7 @@ void JITCore::RegisterMiscHandlers() {
REGISTER_OP(PRINT, Print);
REGISTER_OP(GETROUNDINGMODE, GetRoundingMode);
REGISTER_OP(SETROUNDINGMODE, SetRoundingMode);
REGISTER_OP(INVALIDATEFLAGS, NoOp);
#undef REGISTER_OP
}
}
+22 -11
View File
@@ -144,6 +144,11 @@ void OpDispatchBuilder::NOPOp(OpcodeArgs) {
void OpDispatchBuilder::RETOp(OpcodeArgs) {
uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4;
// ABI Optimization: Flags don't survive calls or rets
if (CTX->Config.ABILocalFlags) {
_InvalidateFlags();
}
auto Constant = _Constant(GPRSize);
auto OldSP = _LoadContext(GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RSP]), GPRClass);
@@ -622,6 +627,12 @@ void OpDispatchBuilder::CALLOp(OpcodeArgs) {
uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4;
BlockSetRIP = true;
// ABI Optimization: Flags don't survive calls or rets
if (CTX->Config.ABILocalFlags) {
_InvalidateFlags();
}
auto ConstantPC = _Constant(Op->PC + Op->InstSize);
OrderedNode *JMPPCOffset = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, -1);
@@ -4721,7 +4732,7 @@ void OpDispatchBuilder::GenerateFlags_ADC(FEXCore::X86Tables::DecodedOp Op, Orde
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto PopCountOp = _Popcount(_And(Res, _Constant(0xFF)));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -4788,7 +4799,7 @@ void OpDispatchBuilder::GenerateFlags_SBB(FEXCore::X86Tables::DecodedOp Op, Orde
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto PopCountOp = _Popcount(_And(Res, _Constant(0xFF)));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -4854,7 +4865,7 @@ void OpDispatchBuilder::GenerateFlags_SUB(FEXCore::X86Tables::DecodedOp Op, Orde
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -4909,7 +4920,7 @@ void OpDispatchBuilder::GenerateFlags_ADD(FEXCore::X86Tables::DecodedOp Op, Orde
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -5019,7 +5030,7 @@ void OpDispatchBuilder::GenerateFlags_Logical(FEXCore::X86Tables::DecodedOp Op,
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -5056,7 +5067,7 @@ void OpDispatchBuilder::GenerateFlags_ShiftLeft(FEXCore::X86Tables::DecodedOp Op
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -5102,7 +5113,7 @@ void OpDispatchBuilder::GenerateFlags_ShiftRight(FEXCore::X86Tables::DecodedOp O
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -5148,7 +5159,7 @@ void OpDispatchBuilder::GenerateFlags_SignShiftRight(FEXCore::X86Tables::Decoded
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -5194,7 +5205,7 @@ void OpDispatchBuilder::GenerateFlags_ShiftLeftImmediate(FEXCore::X86Tables::Dec
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -5241,7 +5252,7 @@ void OpDispatchBuilder::GenerateFlags_SignShiftRightImmediate(FEXCore::X86Tables
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
@@ -5290,7 +5301,7 @@ void OpDispatchBuilder::GenerateFlags_ShiftRightImmediate(FEXCore::X86Tables::De
}
// PF
{
if (!CTX->Config.ABINoPF) {
auto EightBitMask = _Constant(0xFF);
auto PopCountOp = _Popcount(_And(Res, EightBitMask));
auto XorOp = _Xor(PopCountOp, _Constant(1));
+5
View File
@@ -89,6 +89,11 @@
]
},
"InvalidateFlags": {
"OpClass": "Misc",
"HasSideEffects": true
},
"EndBlock": {
"HasSideEffects": true,
"OpClass": "Misc",
@@ -42,6 +42,9 @@ bool DeadFlagStoreElimination::Run(IREmitter *IREmit) {
auto Op = IROp->CW<IR::IROp_StoreFlag>();
FlagMap[BlockNode].writes |= 1 << Op->Flag;
}
else if (IROp->Op == OP_INVALIDATEFLAGS) {
FlagMap[BlockNode].writes = -1;
}
else if (IROp->Op == OP_LOADFLAG) {
auto Op = IROp->CW<IR::IROp_LoadFlag>();
FlagMap[BlockNode].reads |= 1 << Op->Flag;
+3 -1
View File
@@ -18,7 +18,9 @@ namespace FEXCore::Config {
CONFIG_EMULATED_CPU_CORES,
CONFIG_TSO_ENABLED,
CONFIG_SMC_CHECKS,
CONFIG_DUMPIR
CONFIG_ABI_LOCAL_FLAGS,
CONFIG_ABI_NO_PF,
CONFIG_DUMPIR,
};
enum ConfigCore {
+42 -22
View File
@@ -48,29 +48,23 @@ namespace FEX::ArgLoader {
.dest("MaxInst")
.help("Maximum number of instructions to stick in a block")
.set_default(~0U);
CPUGroup.add_option("-m", "--multiblock")
.dest("Multiblock")
.action("store_true")
.help("Enable Multiblock code compilation");
CPUGroup.add_option("--no-multiblock")
.dest("Multiblock")
.action("store_false")
.help("Enable Multiblock code compilation");
CPUGroup.add_option("-G", "--gdb")
.dest("GdbServer")
.action("store_true")
.help("Enables the GDB server");
CPUGroup.add_option("-m", "--multiblock")
.dest("Multiblock")
.action("store_true")
.help("Enable Multiblock code compilation");
CPUGroup.add_option("--no-multiblock")
.dest("Multiblock")
.action("store_false")
.help("Enable Multiblock code compilation");
CPUGroup.add_option("-G", "--gdb")
.dest("GdbServer")
.action("store_true")
.help("Enables the GDB server");
CPUGroup.add_option("-T", "--Threads")
.dest("Threads")
.help("Number of physical hardware threads to tell the process we have")
.set_default(1);
CPUGroup.add_option("--disable-tso")
.dest("TSOEnabled")
.action("store_false")
.help("Disables TSO IR ops. Highly likely to break any threaded application")
.set_default(true);
CPUGroup.add_option("-T", "--Threads")
.dest("Threads")
.help("Number of physical hardware threads to tell the process we have")
.set_default(1);
CPUGroup.add_option("--smc-full-checks")
.dest("SMCChecks")
@@ -78,6 +72,24 @@ namespace FEX::ArgLoader {
.help("Checks code for modification before execution. Slow.")
.set_default(false);
CPUGroup.add_option("--unsafe-no-tso")
.dest("TSOEnabled")
.action("store_false")
.help("Disables TSO IR ops. Highly likely to break any threaded application")
.set_default(true);
CPUGroup.add_option("--unsafe-local-flags")
.dest("AbiLocalFlags")
.action("store_true")
.help("Assumes flags are not used across calls. Hand-written asm could violate this assumption")
.set_default(false);
CPUGroup.add_option("--unsafe-no-pf")
.dest("AbiNoPF")
.action("store_true")
.help("Does not calculate the parity flag on integer operations")
.set_default(false);
Parser.add_option_group(CPUGroup);
}
{
@@ -208,6 +220,14 @@ namespace FEX::ArgLoader {
bool SMCChecks = Options.get("SMCChecks");
Config::Add("SMCChecks", std::to_string(SMCChecks));
}
if (Options.is_set_by_user("AbiLocalFlags")) {
bool AbiLocalFlags = Options.get("AbiLocalFlags");
Config::Add("AbiLocalFlags", std::to_string(AbiLocalFlags));
}
if (Options.is_set_by_user("AbiNoPF")) {
bool AbiNoPF = Options.get("AbiNoPF");
Config::Add("AbiNoPF", std::to_string(AbiNoPF));
}
}
{
+4
View File
@@ -111,6 +111,8 @@ int main(int argc, char **argv, char **const envp) {
FEX::Config::Value<std::string> DumpIR{"DumpIR", "no"};
FEX::Config::Value<bool> TSOEnabledConfig{"TSOEnabled", true};
FEX::Config::Value<bool> SMCChecksConfig{"SMCChecks", false};
FEX::Config::Value<bool> ABILocalFlags{"ABILocalFlags", false};
FEX::Config::Value<bool> AbiNoPF{"AbiNoPF", false};
::SilentLog = SilentLog();
@@ -156,6 +158,8 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_EMULATED_CPU_CORES, ThreadsConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_TSO_ENABLED, TSOEnabledConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_SMC_CHECKS, SMCChecksConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_LOCAL_FLAGS, ABILocalFlags());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_NO_PF, AbiNoPF());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_DUMPIR, DumpIR());
FEXCore::Context::SetCustomCPUBackendFactory(CTX, VMFactory::CPUCreationFactory);
+6
View File
@@ -60,7 +60,10 @@ int main(int argc, char **argv, char **const envp) {
FEX::Config::Value<uint64_t> BlockSizeConfig{"MaxInst", 1};
FEX::Config::Value<bool> SingleStepConfig{"SingleStep", false};
FEX::Config::Value<bool> MultiblockConfig{"Multiblock", false};
FEX::Config::Value<bool> TSOEnabledConfig{"TSOEnabled", true};
FEX::Config::Value<bool> SMCChecksConfig{"SMCChecks", false};
FEX::Config::Value<bool> ABILocalFlags{"ABILocalFlags", false};
FEX::Config::Value<bool> AbiNoPF{"AbiNoPF", false};
auto Args = FEX::ArgLoader::Get();
@@ -78,7 +81,10 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_SINGLESTEP, SingleStepConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_MAXBLOCKINST, BlockSizeConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_IS64BIT_MODE, Loader.Is64BitMode());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_TSO_ENABLED, TSOEnabledConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_SMC_CHECKS, SMCChecksConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_LOCAL_FLAGS, ABILocalFlags());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_NO_PF, AbiNoPF());
FEXCore::Context::SetCustomCPUBackendFactory(CTX, HostCPUFactory::HostCPUCreationFactory);
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);