[Lint] Added InsertBraces to linter to unify codebase to one standard
This commit is contained in:
@@ -6,6 +6,7 @@ SortIncludes: true
|
|||||||
KeepEmptyLines:
|
KeepEmptyLines:
|
||||||
AtStartOfFile: false
|
AtStartOfFile: false
|
||||||
InsertNewlineAtEOF: true
|
InsertNewlineAtEOF: true
|
||||||
|
InsertBraces: true
|
||||||
|
|
||||||
# Regroup causes unnecessary noise due to clang-format bug.
|
# Regroup causes unnecessary noise due to clang-format bug.
|
||||||
IncludeBlocks: Preserve
|
IncludeBlocks: Preserve
|
||||||
|
|||||||
@@ -191,9 +191,13 @@ class EmulatorApp final : public xe::ui::WindowedApp {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
for (const auto& creator : creators_) {
|
for (const auto& creator : creators_) {
|
||||||
if (!creator.is_available()) continue;
|
if (!creator.is_available()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto instance = creator.instantiate(std::forward<Args>(args)...);
|
auto instance = creator.instantiate(std::forward<Args>(args)...);
|
||||||
if (!instance) continue;
|
if (!instance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -124,7 +124,9 @@ ProcessAudioResult ProcessAudioLoop(AudioMediaPlayer* player,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = avcodec_receive_frame(avctx, frame);
|
ret = avcodec_receive_frame(avctx, frame);
|
||||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break;
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
XELOGW("Error during decoding: {:X}", ret);
|
XELOGW("Error during decoding: {:X}", ret);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -273,7 +273,9 @@ void XAudio2AudioDriver::Resume() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void XAudio2AudioDriver::SetVolume(float volume) {
|
void XAudio2AudioDriver::SetVolume(float volume) {
|
||||||
if (cvars::mute) return;
|
if (cvars::mute) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (api_minor_version_ >= 8) {
|
if (api_minor_version_ >= 8) {
|
||||||
objects_.api_2_8.pcm_voice->SetVolume(volume);
|
objects_.api_2_8.pcm_voice->SetVolume(volume);
|
||||||
|
|||||||
@@ -205,7 +205,9 @@ ConfigVar<T>::ConfigVar(const char* name, T* default_value,
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void CommandVar<T>::UpdateValue() {
|
void CommandVar<T>::UpdateValue() {
|
||||||
if (commandline_value_) return SetValue(*commandline_value_);
|
if (commandline_value_) {
|
||||||
|
return SetValue(*commandline_value_);
|
||||||
|
}
|
||||||
return SetValue(default_value_);
|
return SetValue(default_value_);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -213,8 +215,12 @@ void ConfigVar<T>::UpdateValue() {
|
|||||||
if (this->commandline_value_) {
|
if (this->commandline_value_) {
|
||||||
return this->SetValue(*this->commandline_value_);
|
return this->SetValue(*this->commandline_value_);
|
||||||
}
|
}
|
||||||
if (game_config_value_) return this->SetValue(*game_config_value_);
|
if (game_config_value_) {
|
||||||
if (config_value_) return this->SetValue(*config_value_);
|
return this->SetValue(*game_config_value_);
|
||||||
|
}
|
||||||
|
if (config_value_) {
|
||||||
|
return this->SetValue(*config_value_);
|
||||||
|
}
|
||||||
return this->SetValue(this->default_value_);
|
return this->SetValue(this->default_value_);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -268,7 +274,9 @@ bool ConfigVar<T>::is_transient() const {
|
|||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
std::string ConfigVar<T>::config_value() const {
|
std::string ConfigVar<T>::config_value() const {
|
||||||
if (config_value_) return this->ToString(*config_value_);
|
if (config_value_) {
|
||||||
|
return this->ToString(*config_value_);
|
||||||
|
}
|
||||||
return this->ToString(this->default_value_);
|
return this->ToString(this->default_value_);
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|||||||
@@ -143,7 +143,9 @@ class xe_unlikely_mutex {
|
|||||||
#if XE_ARCH_AMD64 == 1
|
#if XE_ARCH_AMD64 == 1
|
||||||
_mm_pause();
|
_mm_pause();
|
||||||
#endif
|
#endif
|
||||||
if (_tryget()) return;
|
if (_tryget()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Fall back to yielding
|
// Fall back to yielding
|
||||||
while (!_tryget()) {
|
while (!_tryget()) {
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ TEST_CASE("Fence") {
|
|||||||
|
|
||||||
pFence->Signal();
|
pFence->Signal();
|
||||||
|
|
||||||
for (auto& t : threads) t.join();
|
for (auto& t : threads) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
REQUIRE(finished.load() == threads.size());
|
REQUIRE(finished.load() == threads.size());
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
|
||||||
|
|||||||
@@ -417,7 +417,9 @@ class PosixCondition<Semaphore> final : public PosixConditionBase {
|
|||||||
if (count_ + release_count > maximum_count_) {
|
if (count_ + release_count > maximum_count_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (out_previous_count) *out_previous_count = count_;
|
if (out_previous_count) {
|
||||||
|
*out_previous_count = count_;
|
||||||
|
}
|
||||||
count_ += release_count;
|
count_ += release_count;
|
||||||
cond_.notify_all();
|
cond_.notify_all();
|
||||||
return true;
|
return true;
|
||||||
@@ -583,7 +585,9 @@ class PosixCondition<Thread> final : public PosixConditionBase {
|
|||||||
ThreadStartData* start_data) {
|
ThreadStartData* start_data) {
|
||||||
start_data->create_suspended = params.create_suspended;
|
start_data->create_suspended = params.create_suspended;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
if (pthread_attr_init(&attr) != 0) return false;
|
if (pthread_attr_init(&attr) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (pthread_attr_setstacksize(&attr, params.stack_size) != 0) {
|
if (pthread_attr_setstacksize(&attr, params.stack_size) != 0) {
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
return false;
|
return false;
|
||||||
@@ -782,8 +786,12 @@ class PosixCondition<Thread> final : public PosixConditionBase {
|
|||||||
// Center: fifo 16 → nice 0.
|
// Center: fifo 16 → nice 0.
|
||||||
int nice_val = 16 - new_priority;
|
int nice_val = 16 - new_priority;
|
||||||
// Clamp to valid nice range.
|
// Clamp to valid nice range.
|
||||||
if (nice_val < -20) nice_val = -20;
|
if (nice_val < -20) {
|
||||||
if (nice_val > 19) nice_val = 19;
|
nice_val = -20;
|
||||||
|
}
|
||||||
|
if (nice_val > 19) {
|
||||||
|
nice_val = 19;
|
||||||
|
}
|
||||||
if (tid_ > 0) {
|
if (tid_ > 0) {
|
||||||
setpriority(PRIO_PROCESS, tid_, nice_val);
|
setpriority(PRIO_PROCESS, tid_, nice_val);
|
||||||
}
|
}
|
||||||
@@ -1027,9 +1035,13 @@ WaitResult Wait(WaitHandle* wait_handle, bool is_alertable,
|
|||||||
if (posix_wait_handle == nullptr) {
|
if (posix_wait_handle == nullptr) {
|
||||||
return WaitResult::kFailed;
|
return WaitResult::kFailed;
|
||||||
}
|
}
|
||||||
if (is_alertable) alertable_state_ = true;
|
if (is_alertable) {
|
||||||
|
alertable_state_ = true;
|
||||||
|
}
|
||||||
auto result = posix_wait_handle->condition().Wait(timeout);
|
auto result = posix_wait_handle->condition().Wait(timeout);
|
||||||
if (is_alertable) alertable_state_ = false;
|
if (is_alertable) {
|
||||||
|
alertable_state_ = false;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1045,11 +1057,15 @@ WaitResult SignalAndWait(WaitHandle* wait_handle_to_signal,
|
|||||||
posix_wait_handle_to_wait_on == nullptr) {
|
posix_wait_handle_to_wait_on == nullptr) {
|
||||||
return WaitResult::kFailed;
|
return WaitResult::kFailed;
|
||||||
}
|
}
|
||||||
if (is_alertable) alertable_state_ = true;
|
if (is_alertable) {
|
||||||
|
alertable_state_ = true;
|
||||||
|
}
|
||||||
if (posix_wait_handle_to_signal->condition().Signal()) {
|
if (posix_wait_handle_to_signal->condition().Signal()) {
|
||||||
result = posix_wait_handle_to_wait_on->condition().Wait(timeout);
|
result = posix_wait_handle_to_wait_on->condition().Wait(timeout);
|
||||||
}
|
}
|
||||||
if (is_alertable) alertable_state_ = false;
|
if (is_alertable) {
|
||||||
|
alertable_state_ = false;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1066,10 +1082,14 @@ std::pair<WaitResult, size_t> WaitMultiple(WaitHandle* wait_handles[],
|
|||||||
}
|
}
|
||||||
conditions.push_back(&handle->condition());
|
conditions.push_back(&handle->condition());
|
||||||
}
|
}
|
||||||
if (is_alertable) alertable_state_ = true;
|
if (is_alertable) {
|
||||||
|
alertable_state_ = true;
|
||||||
|
}
|
||||||
auto result = PosixConditionBase::WaitMultiple(std::move(conditions),
|
auto result = PosixConditionBase::WaitMultiple(std::move(conditions),
|
||||||
wait_all, timeout);
|
wait_all, timeout);
|
||||||
if (is_alertable) alertable_state_ = false;
|
if (is_alertable) {
|
||||||
|
alertable_state_ = false;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1305,7 +1325,9 @@ std::unique_ptr<Thread> Thread::Create(CreationParameters params,
|
|||||||
install_signal_handler(SignalType::kThreadTerminate);
|
install_signal_handler(SignalType::kThreadTerminate);
|
||||||
#endif
|
#endif
|
||||||
auto thread = std::make_unique<PosixThread>();
|
auto thread = std::make_unique<PosixThread>();
|
||||||
if (!thread->Initialize(params, std::move(start_routine))) return nullptr;
|
if (!thread->Initialize(params, std::move(start_routine))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
assert_not_null(thread);
|
assert_not_null(thread);
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,15 @@ std::filesystem::path config_path;
|
|||||||
std::string game_config_suffix = ".config.toml";
|
std::string game_config_suffix = ".config.toml";
|
||||||
|
|
||||||
bool sortCvar(cvar::IConfigVar* a, cvar::IConfigVar* b) {
|
bool sortCvar(cvar::IConfigVar* a, cvar::IConfigVar* b) {
|
||||||
if (a->category() < b->category()) return true;
|
if (a->category() < b->category()) {
|
||||||
if (a->category() > b->category()) return false;
|
return true;
|
||||||
if (a->name() < b->name()) return true;
|
}
|
||||||
|
if (a->category() > b->category()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a->name() < b->name()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,9 +185,15 @@ void SaveConfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(vars.begin(), vars.end(), [](auto a, auto b) {
|
std::sort(vars.begin(), vars.end(), [](auto a, auto b) {
|
||||||
if (a->category() < b->category()) return true;
|
if (a->category() < b->category()) {
|
||||||
if (a->category() > b->category()) return false;
|
return true;
|
||||||
if (a->name() < b->name()) return true;
|
}
|
||||||
|
if (a->category() > b->category()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a->name() < b->name()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ static size_t WriteULEB128(uint8_t* p, uint64_t value) {
|
|||||||
do {
|
do {
|
||||||
uint8_t byte = value & 0x7F;
|
uint8_t byte = value & 0x7F;
|
||||||
value >>= 7;
|
value >>= 7;
|
||||||
if (value) byte |= 0x80;
|
if (value) {
|
||||||
|
byte |= 0x80;
|
||||||
|
}
|
||||||
p[count++] = byte;
|
p[count++] = byte;
|
||||||
} while (value);
|
} while (value);
|
||||||
return count;
|
return count;
|
||||||
|
|||||||
@@ -361,8 +361,12 @@ inline void PrepareVmxFpSources(A64Emitter& e, const T1& op1, const T2& op2,
|
|||||||
int s1 = SrcVReg(e, op1, 0);
|
int s1 = SrcVReg(e, op1, 0);
|
||||||
int s2 = SrcVReg(e, op2, 1);
|
int s2 = SrcVReg(e, op2, 1);
|
||||||
// Copy to scratch v0/v1 so we don't modify live allocated registers.
|
// Copy to scratch v0/v1 so we don't modify live allocated registers.
|
||||||
if (s1 != 0) e.mov(VReg(0).b16, VReg(s1).b16);
|
if (s1 != 0) {
|
||||||
if (s2 != 1) e.mov(VReg(1).b16, VReg(s2).b16);
|
e.mov(VReg(0).b16, VReg(s1).b16);
|
||||||
|
}
|
||||||
|
if (s2 != 1) {
|
||||||
|
e.mov(VReg(1).b16, VReg(s2).b16);
|
||||||
|
}
|
||||||
// Flush denormal inputs in software only if FPCR.FZ doesn't handle it.
|
// Flush denormal inputs in software only if FPCR.FZ doesn't handle it.
|
||||||
if (!e.IsFeatureEnabled(xe::arm64::kA64FZFlushesInputs)) {
|
if (!e.IsFeatureEnabled(xe::arm64::kA64FZFlushesInputs)) {
|
||||||
FlushDenormals_V128(e, 0);
|
FlushDenormals_V128(e, 0);
|
||||||
|
|||||||
@@ -271,30 +271,33 @@ struct VECTOR_ADD
|
|||||||
switch (part_type) {
|
switch (part_type) {
|
||||||
case INT8_TYPE:
|
case INT8_TYPE:
|
||||||
if (saturate) {
|
if (saturate) {
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uqadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.uqadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
else
|
} else {
|
||||||
e.sqadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.sqadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.add(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.add(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INT16_TYPE:
|
case INT16_TYPE:
|
||||||
if (saturate) {
|
if (saturate) {
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uqadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.uqadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
else
|
} else {
|
||||||
e.sqadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.sqadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.add(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.add(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INT32_TYPE:
|
case INT32_TYPE:
|
||||||
if (saturate) {
|
if (saturate) {
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uqadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.uqadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
else
|
} else {
|
||||||
e.sqadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.sqadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.add(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.add(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
}
|
}
|
||||||
@@ -328,30 +331,33 @@ struct VECTOR_SUB
|
|||||||
switch (part_type) {
|
switch (part_type) {
|
||||||
case INT8_TYPE:
|
case INT8_TYPE:
|
||||||
if (saturate) {
|
if (saturate) {
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uqsub(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.uqsub(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
else
|
} else {
|
||||||
e.sqsub(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.sqsub(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.sub(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.sub(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INT16_TYPE:
|
case INT16_TYPE:
|
||||||
if (saturate) {
|
if (saturate) {
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uqsub(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.uqsub(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
else
|
} else {
|
||||||
e.sqsub(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.sqsub(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.sub(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.sub(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INT32_TYPE:
|
case INT32_TYPE:
|
||||||
if (saturate) {
|
if (saturate) {
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uqsub(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.uqsub(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
else
|
} else {
|
||||||
e.sqsub(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.sqsub(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.sub(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.sub(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
}
|
}
|
||||||
@@ -381,22 +387,25 @@ struct VECTOR_MAX
|
|||||||
int d = i.dest.reg().getIdx();
|
int d = i.dest.reg().getIdx();
|
||||||
switch (part_type) {
|
switch (part_type) {
|
||||||
case INT8_TYPE:
|
case INT8_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.umax(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.umax(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
else
|
} else {
|
||||||
e.smax(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.smax(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case INT16_TYPE:
|
case INT16_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.umax(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.umax(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
else
|
} else {
|
||||||
e.smax(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.smax(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case INT32_TYPE:
|
case INT32_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.umax(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.umax(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
else
|
} else {
|
||||||
e.smax(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.smax(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert_unhandled_case(part_type);
|
assert_unhandled_case(part_type);
|
||||||
@@ -441,22 +450,25 @@ struct VECTOR_MIN
|
|||||||
int d = i.dest.reg().getIdx();
|
int d = i.dest.reg().getIdx();
|
||||||
switch (part_type) {
|
switch (part_type) {
|
||||||
case INT8_TYPE:
|
case INT8_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.umin(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.umin(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
else
|
} else {
|
||||||
e.smin(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.smin(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case INT16_TYPE:
|
case INT16_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.umin(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.umin(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
else
|
} else {
|
||||||
e.smin(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.smin(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case INT32_TYPE:
|
case INT32_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.umin(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.umin(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
else
|
} else {
|
||||||
e.smin(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.smin(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert_unhandled_case(part_type);
|
assert_unhandled_case(part_type);
|
||||||
@@ -815,22 +827,25 @@ struct VECTOR_AVERAGE
|
|||||||
// ARM64 has native rounding halving add: (a + b + 1) >> 1.
|
// ARM64 has native rounding halving add: (a + b + 1) >> 1.
|
||||||
switch (part_type) {
|
switch (part_type) {
|
||||||
case INT8_TYPE:
|
case INT8_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.urhadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.urhadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
else
|
} else {
|
||||||
e.srhadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
e.srhadd(VReg(d).b16, VReg(s1).b16, VReg(s2).b16);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case INT16_TYPE:
|
case INT16_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.urhadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.urhadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
else
|
} else {
|
||||||
e.srhadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
e.srhadd(VReg(d).h8, VReg(s1).h8, VReg(s2).h8);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case INT32_TYPE:
|
case INT32_TYPE:
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.urhadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.urhadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
else
|
} else {
|
||||||
e.srhadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
e.srhadd(VReg(d).s4, VReg(s1).s4, VReg(s2).s4);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert_unhandled_case(part_type);
|
assert_unhandled_case(part_type);
|
||||||
@@ -1023,7 +1038,9 @@ struct SWIZZLE
|
|||||||
uint8_t w3 = (swizzle_mask >> 6) & 0x3;
|
uint8_t w3 = (swizzle_mask >> 6) & 0x3;
|
||||||
if (w0 == 0 && w1 == 1 && w2 == 2 && w3 == 3) {
|
if (w0 == 0 && w1 == 1 && w2 == 2 && w3 == 3) {
|
||||||
// Identity.
|
// Identity.
|
||||||
if (d != s) e.mov(VReg(d).b16, VReg(s).b16);
|
if (d != s) {
|
||||||
|
e.mov(VReg(d).b16, VReg(s).b16);
|
||||||
|
}
|
||||||
} else if (w0 == w1 && w1 == w2 && w2 == w3) {
|
} else if (w0 == w1 && w1 == w2 && w2 == w3) {
|
||||||
// Broadcast single lane.
|
// Broadcast single lane.
|
||||||
e.dup(VReg(d).s4, VReg(s).s4[w0]);
|
e.dup(VReg(d).s4, VReg(s).s4[w0]);
|
||||||
@@ -1773,18 +1790,20 @@ struct UNPACK : Sequence<UNPACK, I<OPCODE_UNPACK, V128Op, V128Op>> {
|
|||||||
e.rev32(VReg(d).h8, VReg(s).h8);
|
e.rev32(VReg(d).h8, VReg(s).h8);
|
||||||
if (to_hi) {
|
if (to_hi) {
|
||||||
// PPC high bytes are in the NEON low half after rev32.
|
// PPC high bytes are in the NEON low half after rev32.
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uxtl(VReg(d).h8, VReg(d).b8);
|
e.uxtl(VReg(d).h8, VReg(d).b8);
|
||||||
else
|
} else {
|
||||||
e.sxtl(VReg(d).h8, VReg(d).b8);
|
e.sxtl(VReg(d).h8, VReg(d).b8);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// PPC low bytes are in the NEON high half after rev32.
|
// PPC low bytes are in the NEON high half after rev32.
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uxtl2(VReg(d).h8, VReg(d).b16);
|
e.uxtl2(VReg(d).h8, VReg(d).b16);
|
||||||
else
|
} else {
|
||||||
e.sxtl2(VReg(d).h8, VReg(d).b16);
|
e.sxtl2(VReg(d).h8, VReg(d).b16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
static void Emit16_IN_32(A64Emitter& e, const EmitArgType& i,
|
static void Emit16_IN_32(A64Emitter& e, const EmitArgType& i,
|
||||||
uint32_t flags) {
|
uint32_t flags) {
|
||||||
int s = SrcVReg(e, i.src1, 0);
|
int s = SrcVReg(e, i.src1, 0);
|
||||||
@@ -1797,17 +1816,19 @@ struct UNPACK : Sequence<UNPACK, I<OPCODE_UNPACK, V128Op, V128Op>> {
|
|||||||
// 32-bit pairs to fix the halfword ordering.
|
// 32-bit pairs to fix the halfword ordering.
|
||||||
if (to_hi) {
|
if (to_hi) {
|
||||||
// PPC high halfwords → NEON low half.
|
// PPC high halfwords → NEON low half.
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uxtl(VReg(d).s4, VReg(s).h4);
|
e.uxtl(VReg(d).s4, VReg(s).h4);
|
||||||
else
|
} else {
|
||||||
e.sxtl(VReg(d).s4, VReg(s).h4);
|
e.sxtl(VReg(d).s4, VReg(s).h4);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// PPC low halfwords → NEON high half.
|
// PPC low halfwords → NEON high half.
|
||||||
if (is_unsigned)
|
if (is_unsigned) {
|
||||||
e.uxtl2(VReg(d).s4, VReg(s).h8);
|
e.uxtl2(VReg(d).s4, VReg(s).h8);
|
||||||
else
|
} else {
|
||||||
e.sxtl2(VReg(d).s4, VReg(s).h8);
|
e.sxtl2(VReg(d).s4, VReg(s).h8);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
e.rev64(VReg(d).s4, VReg(d).s4);
|
e.rev64(VReg(d).s4, VReg(d).s4);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -606,10 +606,11 @@ static void EmitFmaWithPpcNan_F64(A64Emitter& e, DReg dest, DReg s1, DReg s2,
|
|||||||
e.b(VS, nan_path);
|
e.b(VS, nan_path);
|
||||||
|
|
||||||
// Fast path: no NaN input → hardware FMA.
|
// Fast path: no NaN input → hardware FMA.
|
||||||
if (is_sub)
|
if (is_sub) {
|
||||||
e.fnmsub(dest, s1, s2, s3);
|
e.fnmsub(dest, s1, s2, s3);
|
||||||
else
|
} else {
|
||||||
e.fmadd(dest, s1, s2, s3);
|
e.fmadd(dest, s1, s2, s3);
|
||||||
|
}
|
||||||
// If result is NaN (0*inf or inf-inf), canonicalize to PPC default.
|
// If result is NaN (0*inf or inf-inf), canonicalize to PPC default.
|
||||||
e.fcmp(dest, dest);
|
e.fcmp(dest, dest);
|
||||||
e.b(VC, done);
|
e.b(VC, done);
|
||||||
@@ -656,10 +657,11 @@ static void EmitFmaWithPpcNan_F32(A64Emitter& e, SReg dest, SReg s1, SReg s2,
|
|||||||
e.fccmp(s3, s3, 0b0001, VC);
|
e.fccmp(s3, s3, 0b0001, VC);
|
||||||
e.b(VS, nan_path);
|
e.b(VS, nan_path);
|
||||||
|
|
||||||
if (is_sub)
|
if (is_sub) {
|
||||||
e.fnmsub(dest, s1, s2, s3);
|
e.fnmsub(dest, s1, s2, s3);
|
||||||
else
|
} else {
|
||||||
e.fmadd(dest, s1, s2, s3);
|
e.fmadd(dest, s1, s2, s3);
|
||||||
|
}
|
||||||
e.fcmp(dest, dest);
|
e.fcmp(dest, dest);
|
||||||
e.b(VC, done);
|
e.b(VC, done);
|
||||||
e.mov(e.w0, static_cast<uint64_t>(0xFFC00000u));
|
e.mov(e.w0, static_cast<uint64_t>(0xFFC00000u));
|
||||||
@@ -1074,7 +1076,9 @@ struct ADD_CARRY_I16
|
|||||||
e.add(e.w0, e.w0, i.src2);
|
e.add(e.w0, e.w0, i.src2);
|
||||||
}
|
}
|
||||||
if (i.src3.is_constant) {
|
if (i.src3.is_constant) {
|
||||||
if (i.src3.constant()) e.add(e.w0, e.w0, 1);
|
if (i.src3.constant()) {
|
||||||
|
e.add(e.w0, e.w0, 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.add(e.w0, e.w0, i.src3);
|
e.add(e.w0, e.w0, i.src3);
|
||||||
}
|
}
|
||||||
@@ -1098,7 +1102,9 @@ struct ADD_CARRY_I32
|
|||||||
e.add(e.w0, e.w0, i.src2);
|
e.add(e.w0, e.w0, i.src2);
|
||||||
}
|
}
|
||||||
if (i.src3.is_constant) {
|
if (i.src3.is_constant) {
|
||||||
if (i.src3.constant()) e.add(e.w0, e.w0, 1);
|
if (i.src3.constant()) {
|
||||||
|
e.add(e.w0, e.w0, 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
e.add(e.w0, e.w0, i.src3);
|
e.add(e.w0, e.w0, i.src3);
|
||||||
}
|
}
|
||||||
@@ -1120,7 +1126,9 @@ struct ADD_CARRY_I64
|
|||||||
e.add(e.x0, e.x0, i.src2);
|
e.add(e.x0, e.x0, i.src2);
|
||||||
}
|
}
|
||||||
if (i.src3.is_constant) {
|
if (i.src3.is_constant) {
|
||||||
if (i.src3.constant()) e.add(e.x0, e.x0, 1);
|
if (i.src3.constant()) {
|
||||||
|
e.add(e.x0, e.x0, 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Zero-extend the I8 carry to 64-bit.
|
// Zero-extend the I8 carry to 64-bit.
|
||||||
e.mov(e.w1, i.src3);
|
e.mov(e.w1, i.src3);
|
||||||
@@ -1920,7 +1928,9 @@ struct SHL_V128 : Sequence<SHL_V128, I<OPCODE_SHL, V128Op, V128Op, I8Op>> {
|
|||||||
if (i.src2.is_constant) {
|
if (i.src2.is_constant) {
|
||||||
uint8_t sh = i.src2.constant() & 0x7;
|
uint8_t sh = i.src2.constant() & 0x7;
|
||||||
if (sh == 0) {
|
if (sh == 0) {
|
||||||
if (d != s) e.mov(VReg(d).b16, VReg(s).b16);
|
if (d != s) {
|
||||||
|
e.mov(VReg(d).b16, VReg(s).b16);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Read carry before writing result (handles dest==src aliasing).
|
// Read carry before writing result (handles dest==src aliasing).
|
||||||
@@ -2045,7 +2055,9 @@ struct SHR_V128 : Sequence<SHR_V128, I<OPCODE_SHR, V128Op, V128Op, I8Op>> {
|
|||||||
if (i.src2.is_constant) {
|
if (i.src2.is_constant) {
|
||||||
uint8_t sh = i.src2.constant() & 0x7;
|
uint8_t sh = i.src2.constant() & 0x7;
|
||||||
if (sh == 0) {
|
if (sh == 0) {
|
||||||
if (d != s) e.mov(VReg(d).b16, VReg(s).b16);
|
if (d != s) {
|
||||||
|
e.mov(VReg(d).b16, VReg(s).b16);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Read carry before writing result (handles dest==src aliasing).
|
// Read carry before writing result (handles dest==src aliasing).
|
||||||
@@ -3972,7 +3984,9 @@ struct MUL_ADD_V128
|
|||||||
|
|
||||||
// Flush s3 → v3, save to stack slot 2.
|
// Flush s3 → v3, save to stack slot 2.
|
||||||
int s3 = SrcVReg(e, i.src3, 3);
|
int s3 = SrcVReg(e, i.src3, 3);
|
||||||
if (s3 != 3) e.mov(VReg(3).b16, VReg(s3).b16);
|
if (s3 != 3) {
|
||||||
|
e.mov(VReg(3).b16, VReg(s3).b16);
|
||||||
|
}
|
||||||
if (!e.IsFeatureEnabled(xe::arm64::kA64FZFlushesInputs)) {
|
if (!e.IsFeatureEnabled(xe::arm64::kA64FZFlushesInputs)) {
|
||||||
FlushDenormals_V128(e, 3, 0, 1);
|
FlushDenormals_V128(e, 3, 0, 1);
|
||||||
}
|
}
|
||||||
@@ -4060,7 +4074,9 @@ struct MUL_SUB_V128
|
|||||||
|
|
||||||
// Flush s3 → v3, save un-negated for NaN fixup.
|
// Flush s3 → v3, save un-negated for NaN fixup.
|
||||||
int s3 = SrcVReg(e, i.src3, 3);
|
int s3 = SrcVReg(e, i.src3, 3);
|
||||||
if (s3 != 3) e.mov(VReg(3).b16, VReg(s3).b16);
|
if (s3 != 3) {
|
||||||
|
e.mov(VReg(3).b16, VReg(s3).b16);
|
||||||
|
}
|
||||||
if (!e.IsFeatureEnabled(xe::arm64::kA64FZFlushesInputs)) {
|
if (!e.IsFeatureEnabled(xe::arm64::kA64FZFlushesInputs)) {
|
||||||
FlushDenormals_V128(e, 3, 0, 1);
|
FlushDenormals_V128(e, 3, 0, 1);
|
||||||
}
|
}
|
||||||
@@ -4493,7 +4509,9 @@ static uint32_t PpcVrsqrtefpLane(uint32_t bits) {
|
|||||||
uint32_t mantissa = bits & 0x007FFFFF;
|
uint32_t mantissa = bits & 0x007FFFFF;
|
||||||
|
|
||||||
// -Inf → QNaN
|
// -Inf → QNaN
|
||||||
if (bits == 0xFF800000u) return 0x7FC00000u;
|
if (bits == 0xFF800000u) {
|
||||||
|
return 0x7FC00000u;
|
||||||
|
}
|
||||||
|
|
||||||
// Denormal or zero (exp == 0)
|
// Denormal or zero (exp == 0)
|
||||||
if (biased_exp == 0) {
|
if (biased_exp == 0) {
|
||||||
@@ -4512,7 +4530,9 @@ static uint32_t PpcVrsqrtefpLane(uint32_t bits) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Negative normal → QNaN
|
// Negative normal → QNaN
|
||||||
if (sign) return 0x7FC00000u;
|
if (sign) {
|
||||||
|
return 0x7FC00000u;
|
||||||
|
}
|
||||||
|
|
||||||
// Normal positive: table lookup + interpolation
|
// Normal positive: table lookup + interpolation
|
||||||
int32_t unbiased_exp = (int32_t)biased_exp - 127;
|
int32_t unbiased_exp = (int32_t)biased_exp - 127;
|
||||||
@@ -4545,7 +4565,9 @@ static uint32_t PpcVrsqrtefpLane(uint32_t bits) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rounding
|
// Rounding
|
||||||
if ((raw & 5) && (raw & 2)) raw += 4;
|
if ((raw & 5) && (raw & 2)) {
|
||||||
|
raw += 4;
|
||||||
|
}
|
||||||
|
|
||||||
// Assemble result
|
// Assemble result
|
||||||
uint32_t res_exp = (uint32_t)((result_exp << 23) + 0x3F800000);
|
uint32_t res_exp = (uint32_t)((result_exp << 23) + 0x3F800000);
|
||||||
|
|||||||
@@ -375,7 +375,9 @@ class CodeCacheBase : public CodeCache {
|
|||||||
size_t old_commit_mark, new_commit_mark;
|
size_t old_commit_mark, new_commit_mark;
|
||||||
do {
|
do {
|
||||||
old_commit_mark = generated_code_commit_mark_;
|
old_commit_mark = generated_code_commit_mark_;
|
||||||
if (high_mark <= old_commit_mark) break;
|
if (high_mark <= old_commit_mark) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
new_commit_mark = old_commit_mark + 16_MiB;
|
new_commit_mark = old_commit_mark + 16_MiB;
|
||||||
if (generated_code_execute_base_ == generated_code_write_base_) {
|
if (generated_code_execute_base_ == generated_code_write_base_) {
|
||||||
xe::memory::AllocFixed(generated_code_execute_base_, new_commit_mark,
|
xe::memory::AllocFixed(generated_code_execute_base_, new_commit_mark,
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ static size_t WriteULEB128(uint8_t* p, uint64_t value) {
|
|||||||
do {
|
do {
|
||||||
uint8_t byte = value & 0x7F;
|
uint8_t byte = value & 0x7F;
|
||||||
value >>= 7;
|
value >>= 7;
|
||||||
if (value) byte |= 0x80;
|
if (value) {
|
||||||
|
byte |= 0x80;
|
||||||
|
}
|
||||||
p[count++] = byte;
|
p[count++] = byte;
|
||||||
} while (value);
|
} while (value);
|
||||||
return count;
|
return count;
|
||||||
|
|||||||
@@ -865,12 +865,13 @@ void X64Emitter::SetReturnAddress(uint64_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Xbyak::Reg64 X64Emitter::GetNativeParam(uint32_t param) {
|
Xbyak::Reg64 X64Emitter::GetNativeParam(uint32_t param) {
|
||||||
if (param == 0)
|
if (param == 0) {
|
||||||
return rdx;
|
return rdx;
|
||||||
else if (param == 1)
|
} else if (param == 1) {
|
||||||
return r8;
|
return r8;
|
||||||
else if (param == 2)
|
} else if (param == 2) {
|
||||||
return r9;
|
return r9;
|
||||||
|
}
|
||||||
|
|
||||||
assert_always();
|
assert_always();
|
||||||
return r9;
|
return r9;
|
||||||
|
|||||||
@@ -957,8 +957,9 @@ struct COMPARE_EQ_I8
|
|||||||
[](X64Emitter& e, const Reg8& src1, int32_t constant) {
|
[](X64Emitter& e, const Reg8& src1, int32_t constant) {
|
||||||
if (constant == 0) {
|
if (constant == 0) {
|
||||||
e.test(src1, src1);
|
e.test(src1, src1);
|
||||||
} else
|
} else {
|
||||||
e.cmp(src1, constant);
|
e.cmp(src1, constant);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
CompareEqDoSete(e, i.instr, i.dest);
|
CompareEqDoSete(e, i.instr, i.dest);
|
||||||
@@ -976,8 +977,9 @@ struct COMPARE_EQ_I16
|
|||||||
[](X64Emitter& e, const Reg16& src1, int32_t constant) {
|
[](X64Emitter& e, const Reg16& src1, int32_t constant) {
|
||||||
if (constant == 0) {
|
if (constant == 0) {
|
||||||
e.test(src1, src1);
|
e.test(src1, src1);
|
||||||
} else
|
} else {
|
||||||
e.cmp(src1, constant);
|
e.cmp(src1, constant);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
CompareEqDoSete(e, i.instr, i.dest);
|
CompareEqDoSete(e, i.instr, i.dest);
|
||||||
@@ -995,8 +997,9 @@ struct COMPARE_EQ_I32
|
|||||||
[](X64Emitter& e, const Reg32& src1, int32_t constant) {
|
[](X64Emitter& e, const Reg32& src1, int32_t constant) {
|
||||||
if (constant == 0) {
|
if (constant == 0) {
|
||||||
e.test(src1, src1);
|
e.test(src1, src1);
|
||||||
} else
|
} else {
|
||||||
e.cmp(src1, constant);
|
e.cmp(src1, constant);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
CompareEqDoSete(e, i.instr, i.dest);
|
CompareEqDoSete(e, i.instr, i.dest);
|
||||||
@@ -1014,8 +1017,9 @@ struct COMPARE_EQ_I64
|
|||||||
[](X64Emitter& e, const Reg64& src1, int32_t constant) {
|
[](X64Emitter& e, const Reg64& src1, int32_t constant) {
|
||||||
if (constant == 0) {
|
if (constant == 0) {
|
||||||
e.test(src1, src1);
|
e.test(src1, src1);
|
||||||
} else
|
} else {
|
||||||
e.cmp(src1, constant);
|
e.cmp(src1, constant);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
CompareEqDoSete(e, i.instr, i.dest);
|
CompareEqDoSete(e, i.instr, i.dest);
|
||||||
|
|||||||
@@ -510,7 +510,9 @@ void RegisterAllocationPass::SortUsageList(Value* value) {
|
|||||||
for (int i = 0; i < insize; i++) {
|
for (int i = 0; i < insize; i++) {
|
||||||
psize++;
|
psize++;
|
||||||
q = q->next;
|
q = q->next;
|
||||||
if (!q) break;
|
if (!q) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// if q hasn't fallen off end, we have two lists to merge
|
// if q hasn't fallen off end, we have two lists to merge
|
||||||
int qsize = insize;
|
int qsize = insize;
|
||||||
|
|||||||
@@ -67,7 +67,9 @@ static bool IsScalarBasicCmp(Opcode op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool SameValueOrEqualConstant(hir::Value* x, hir::Value* y) {
|
static bool SameValueOrEqualConstant(hir::Value* x, hir::Value* y) {
|
||||||
if (x == y) return true;
|
if (x == y) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (x->IsConstant() && y->IsConstant()) {
|
if (x->IsConstant() && y->IsConstant()) {
|
||||||
return x->AsUint64() == y->AsUint64();
|
return x->AsUint64() == y->AsUint64();
|
||||||
@@ -82,12 +84,18 @@ static bool CompareDefsHaveSameOpnds(hir::Value* cmp1, hir::Value* cmp2,
|
|||||||
Opcode* out_r_op) {
|
Opcode* out_r_op) {
|
||||||
auto df1 = cmp1->def;
|
auto df1 = cmp1->def;
|
||||||
auto df2 = cmp2->def;
|
auto df2 = cmp2->def;
|
||||||
if (!df1 || !df2) return false;
|
if (!df1 || !df2) {
|
||||||
if (df1->src1.value != df2->src1.value) return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (df1->src1.value != df2->src1.value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Opcode lop = df1->opcode->num, rop = df2->opcode->num;
|
Opcode lop = df1->opcode->num, rop = df2->opcode->num;
|
||||||
|
|
||||||
if (!IsScalarBasicCmp(lop) || !IsScalarBasicCmp(rop)) return false;
|
if (!IsScalarBasicCmp(lop) || !IsScalarBasicCmp(rop)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SameValueOrEqualConstant(df1->src2.value, df2->src2.value)) {
|
if (!SameValueOrEqualConstant(df1->src2.value, df2->src2.value)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -101,7 +109,9 @@ static bool CompareDefsHaveSameOpnds(hir::Value* cmp1, hir::Value* cmp2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SimplificationPass::CheckOr(hir::Instr* i, hir::HIRBuilder* builder) {
|
bool SimplificationPass::CheckOr(hir::Instr* i, hir::HIRBuilder* builder) {
|
||||||
if (CheckOrXorZero(i)) return true;
|
if (CheckOrXorZero(i)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (i->src1.value == i->src2.value) {
|
if (i->src1.value == i->src2.value) {
|
||||||
auto old1 = i->src1.value;
|
auto old1 = i->src1.value;
|
||||||
@@ -228,7 +238,9 @@ bool SimplificationPass::CheckXor(hir::Instr* i, hir::HIRBuilder* builder) {
|
|||||||
|
|
||||||
uint64_t type_mask = GetScalarTypeMask(i->dest->type);
|
uint64_t type_mask = GetScalarTypeMask(i->dest->type);
|
||||||
|
|
||||||
if (!constant_value) return false;
|
if (!constant_value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (constant_value->AsUint64() == type_mask) {
|
if (constant_value->AsUint64() == type_mask) {
|
||||||
i->Replace(&OPCODE_NOT_info, 0);
|
i->Replace(&OPCODE_NOT_info, 0);
|
||||||
@@ -729,7 +741,9 @@ bool SimplificationPass::CheckSelect(hir::Instr* i, hir::HIRBuilder* builder) {
|
|||||||
|
|
||||||
bool SimplificationPass::CheckScalarConstCmp(hir::Instr* i,
|
bool SimplificationPass::CheckScalarConstCmp(hir::Instr* i,
|
||||||
hir::HIRBuilder* builder) {
|
hir::HIRBuilder* builder) {
|
||||||
if (!IsScalarIntegralType(i->src1.value->type)) return false;
|
if (!IsScalarIntegralType(i->src1.value->type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
auto [constant_value, variable] = i->BinaryValueArrangeAsConstAndVar();
|
auto [constant_value, variable] = i->BinaryValueArrangeAsConstAndVar();
|
||||||
|
|
||||||
if (!constant_value) {
|
if (!constant_value) {
|
||||||
@@ -969,7 +983,9 @@ bool SimplificationPass::CheckSHRByConst(hir::Instr* i,
|
|||||||
bool SimplificationPass::CheckSHR(hir::Instr* i, hir::HIRBuilder* builder) {
|
bool SimplificationPass::CheckSHR(hir::Instr* i, hir::HIRBuilder* builder) {
|
||||||
Value* shr_lhs = i->src1.value;
|
Value* shr_lhs = i->src1.value;
|
||||||
Value* shr_rhs = i->src2.value;
|
Value* shr_rhs = i->src2.value;
|
||||||
if (!shr_lhs || !shr_rhs) return false;
|
if (!shr_lhs || !shr_rhs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (shr_rhs->IsConstant()) {
|
if (shr_rhs->IsConstant()) {
|
||||||
return CheckSHRByConst(i, builder, shr_lhs, shr_rhs->AsUint32());
|
return CheckSHRByConst(i, builder, shr_lhs, shr_rhs->AsUint32());
|
||||||
}
|
}
|
||||||
@@ -1260,7 +1276,9 @@ bool SimplificationPass::SimplifyAndNot(hir::Instr* i,
|
|||||||
|
|
||||||
Instr* def1 = src1->def;
|
Instr* def1 = src1->def;
|
||||||
Instr* def2 = src2->def;
|
Instr* def2 = src2->def;
|
||||||
if (!def1 || !def2) return false;
|
if (!def1 || !def2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Bypass the NOT from an incoming operand and combine it into AND_NOT.
|
// Bypass the NOT from an incoming operand and combine it into AND_NOT.
|
||||||
// If the original NOT does not have any further uses, then the
|
// If the original NOT does not have any further uses, then the
|
||||||
|
|||||||
@@ -94,15 +94,20 @@ class Instr {
|
|||||||
TPredicate&& pred) {
|
TPredicate&& pred) {
|
||||||
auto src1_value = src1.value;
|
auto src1_value = src1.value;
|
||||||
auto src2_value = src2.value;
|
auto src2_value = src2.value;
|
||||||
if (!src1_value || !src2_value) return {nullptr, nullptr};
|
if (!src1_value || !src2_value) {
|
||||||
|
return {nullptr, nullptr};
|
||||||
|
}
|
||||||
|
|
||||||
if (!GetOpcodeInfo()) return {nullptr, nullptr}; // impossible!
|
if (!GetOpcodeInfo()) {
|
||||||
|
return {nullptr, nullptr}; // impossible!
|
||||||
|
}
|
||||||
|
|
||||||
// check if binary opcode taking two values. we dont care if the dest is a
|
// check if binary opcode taking two values. we dont care if the dest is a
|
||||||
// value
|
// value
|
||||||
|
|
||||||
if (!IsOpcodeBinaryValue(GetOpcodeInfo()->signature))
|
if (!IsOpcodeBinaryValue(GetOpcodeInfo()->signature)) {
|
||||||
return {nullptr, nullptr};
|
return {nullptr, nullptr};
|
||||||
|
}
|
||||||
|
|
||||||
if (pred(src1_value)) {
|
if (pred(src1_value)) {
|
||||||
if (pred(src2_value)) {
|
if (pred(src2_value)) {
|
||||||
@@ -142,7 +147,9 @@ if both are constant, return nullptr, nullptr
|
|||||||
const OpcodeInfo* op_ptr) {
|
const OpcodeInfo* op_ptr) {
|
||||||
auto result = BinaryValueArrangeByDefiningOpcode(op_ptr);
|
auto result = BinaryValueArrangeByDefiningOpcode(op_ptr);
|
||||||
|
|
||||||
if (!result.first) return result;
|
if (!result.first) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if (!result.second->IsConstant()) {
|
if (!result.second->IsConstant()) {
|
||||||
return {nullptr, nullptr};
|
return {nullptr, nullptr};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,8 +154,9 @@ int lzxdelta_apply_patch(xe::xex2_delta_patch* patch, size_t patch_len,
|
|||||||
int patch_sz = -4; // 0 byte patches need us to remove 4 byte from next
|
int patch_sz = -4; // 0 byte patches need us to remove 4 byte from next
|
||||||
// patch addr because of patch_data field
|
// patch addr because of patch_data field
|
||||||
if (cur_patch->compressed_len == 0 && cur_patch->uncompressed_len == 0 &&
|
if (cur_patch->compressed_len == 0 && cur_patch->uncompressed_len == 0 &&
|
||||||
cur_patch->new_addr == 0 && cur_patch->old_addr == 0)
|
cur_patch->new_addr == 0 && cur_patch->old_addr == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
switch (cur_patch->compressed_len) {
|
switch (cur_patch->compressed_len) {
|
||||||
case 0: // fill with 0
|
case 0: // fill with 0
|
||||||
std::memset((char*)dest + cur_patch->new_addr, 0,
|
std::memset((char*)dest + cur_patch->new_addr, 0,
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ namespace ppc {
|
|||||||
|
|
||||||
void PadStringBuffer(StringBuffer* str, size_t base, size_t pad) {
|
void PadStringBuffer(StringBuffer* str, size_t base, size_t pad) {
|
||||||
size_t added_len = str->length() - base;
|
size_t added_len = str->length() - base;
|
||||||
if (added_len < pad) str->AppendBytes(kSpaces, kNamePad - added_len);
|
if (added_len < pad) {
|
||||||
|
str->AppendBytes(kSpaces, kNamePad - added_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintDisasm_bcx(const PPCDecodeData& d, StringBuffer* str) {
|
void PrintDisasm_bcx(const PPCDecodeData& d, StringBuffer* str) {
|
||||||
@@ -145,15 +147,23 @@ void PrintDisasm_bcx(const PPCDecodeData& d, StringBuffer* str) {
|
|||||||
if (str_start == str->length()) {
|
if (str_start == str->length()) {
|
||||||
// Default
|
// Default
|
||||||
str->Append("bc");
|
str->Append("bc");
|
||||||
if (d.B.LK()) str->Append('l');
|
if (d.B.LK()) {
|
||||||
if (d.B.AA()) str->Append('a');
|
str->Append('l');
|
||||||
|
}
|
||||||
|
if (d.B.AA()) {
|
||||||
|
str->Append('a');
|
||||||
|
}
|
||||||
PadStringBuffer(str, str_start, kNamePad);
|
PadStringBuffer(str, str_start, kNamePad);
|
||||||
str->AppendFormat("{}", bo);
|
str->AppendFormat("{}", bo);
|
||||||
str->Append(", ");
|
str->Append(", ");
|
||||||
str->AppendFormat("{}", bi);
|
str->AppendFormat("{}", bi);
|
||||||
} else {
|
} else {
|
||||||
if (d.B.LK()) str->Append('l');
|
if (d.B.LK()) {
|
||||||
if (d.B.AA()) str->Append('a');
|
str->Append('l');
|
||||||
|
}
|
||||||
|
if (d.B.AA()) {
|
||||||
|
str->Append('a');
|
||||||
|
}
|
||||||
|
|
||||||
if (sign_char > 0) {
|
if (sign_char > 0) {
|
||||||
str->Append('+');
|
str->Append('+');
|
||||||
|
|||||||
@@ -74,9 +74,13 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
|||||||
// Loops until no changes are made.
|
// Loops until no changes are made.
|
||||||
auto sap = std::make_unique<passes::ConditionalGroupPass>();
|
auto sap = std::make_unique<passes::ConditionalGroupPass>();
|
||||||
sap->AddPass(std::make_unique<passes::SimplificationPass>());
|
sap->AddPass(std::make_unique<passes::SimplificationPass>());
|
||||||
if (validate) sap->AddPass(std::make_unique<passes::ValidationPass>());
|
if (validate) {
|
||||||
|
sap->AddPass(std::make_unique<passes::ValidationPass>());
|
||||||
|
}
|
||||||
sap->AddPass(std::make_unique<passes::ConstantPropagationPass>());
|
sap->AddPass(std::make_unique<passes::ConstantPropagationPass>());
|
||||||
if (validate) sap->AddPass(std::make_unique<passes::ValidationPass>());
|
if (validate) {
|
||||||
|
sap->AddPass(std::make_unique<passes::ValidationPass>());
|
||||||
|
}
|
||||||
compiler_->AddPass(std::move(sap));
|
compiler_->AddPass(std::move(sap));
|
||||||
|
|
||||||
if (backend->machine_info()->supports_extended_load_store) {
|
if (backend->machine_info()->supports_extended_load_store) {
|
||||||
@@ -84,16 +88,21 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
|||||||
// These will save us a lot of HIR opcodes.
|
// These will save us a lot of HIR opcodes.
|
||||||
compiler_->AddPass(
|
compiler_->AddPass(
|
||||||
std::make_unique<passes::MemorySequenceCombinationPass>());
|
std::make_unique<passes::MemorySequenceCombinationPass>());
|
||||||
if (validate)
|
if (validate) {
|
||||||
compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
compiler_->AddPass(std::make_unique<passes::SimplificationPass>());
|
compiler_->AddPass(std::make_unique<passes::SimplificationPass>());
|
||||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
if (validate) {
|
||||||
|
compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||||
|
}
|
||||||
// compiler_->AddPass(std::make_unique<passes::DeadStoreEliminationPass>());
|
// compiler_->AddPass(std::make_unique<passes::DeadStoreEliminationPass>());
|
||||||
// if (validate)
|
// if (validate)
|
||||||
// compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
// compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||||
compiler_->AddPass(std::make_unique<passes::DeadCodeEliminationPass>());
|
compiler_->AddPass(std::make_unique<passes::DeadCodeEliminationPass>());
|
||||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
if (validate) {
|
||||||
|
compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||||
|
}
|
||||||
|
|
||||||
//// Removes all unneeded variables. Try not to add new ones after this.
|
//// Removes all unneeded variables. Try not to add new ones after this.
|
||||||
// compiler_->AddPass(new passes::ValueReductionPass());
|
// compiler_->AddPass(new passes::ValueReductionPass());
|
||||||
@@ -105,7 +114,9 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
|||||||
// registers are assigned and ready to be emitted.
|
// registers are assigned and ready to be emitted.
|
||||||
compiler_->AddPass(std::make_unique<passes::RegisterAllocationPass>(
|
compiler_->AddPass(std::make_unique<passes::RegisterAllocationPass>(
|
||||||
backend->machine_info()));
|
backend->machine_info()));
|
||||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
if (validate) {
|
||||||
|
compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||||
|
}
|
||||||
|
|
||||||
// Must come last. The HIR is not really HIR after this.
|
// Must come last. The HIR is not really HIR after this.
|
||||||
compiler_->AddPass(std::make_unique<passes::FinalizationPass>());
|
compiler_->AddPass(std::make_unique<passes::FinalizationPass>());
|
||||||
|
|||||||
@@ -376,7 +376,9 @@ class TestRunner {
|
|||||||
auto p = memory_->TranslateVirtual(address);
|
auto p = memory_->TranslateVirtual(address);
|
||||||
const char* c = bytes_str.c_str();
|
const char* c = bytes_str.c_str();
|
||||||
while (*c) {
|
while (*c) {
|
||||||
while (*c == ' ') ++c;
|
while (*c == ' ') {
|
||||||
|
++c;
|
||||||
|
}
|
||||||
if (!*c) {
|
if (!*c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -425,7 +427,9 @@ class TestRunner {
|
|||||||
StringBuffer expecteds;
|
StringBuffer expecteds;
|
||||||
StringBuffer actuals;
|
StringBuffer actuals;
|
||||||
while (*c) {
|
while (*c) {
|
||||||
while (*c == ' ') ++c;
|
while (*c == ' ') {
|
||||||
|
++c;
|
||||||
|
}
|
||||||
if (!*c) {
|
if (!*c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -728,7 +732,9 @@ bool RunTests(const std::vector<std::string>& test_names) {
|
|||||||
suite_tests.push_back(&test_case);
|
suite_tests.push_back(&test_case);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (suite_tests.empty()) continue;
|
if (suite_tests.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
++suite_index;
|
++suite_index;
|
||||||
|
|
||||||
int pct =
|
int pct =
|
||||||
@@ -753,7 +759,9 @@ bool RunTests(const std::vector<std::string>& test_names) {
|
|||||||
// instance per thread (avoids shm name collisions between concurrent
|
// instance per thread (avoids shm name collisions between concurrent
|
||||||
// children).
|
// children).
|
||||||
unsigned int num_cores = std::thread::hardware_concurrency();
|
unsigned int num_cores = std::thread::hardware_concurrency();
|
||||||
if (num_cores == 0) num_cores = 4;
|
if (num_cores == 0) {
|
||||||
|
num_cores = 4;
|
||||||
|
}
|
||||||
num_cores = std::max(1u, num_cores * 3 / 4);
|
num_cores = std::max(1u, num_cores * 3 / 4);
|
||||||
|
|
||||||
fprintf(stderr, "Running tests in parallel using %u workers\n", num_cores);
|
fprintf(stderr, "Running tests in parallel using %u workers\n", num_cores);
|
||||||
@@ -795,7 +803,9 @@ bool RunTests(const std::vector<std::string>& test_names) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
size_t idx = test_index.fetch_add(1);
|
size_t idx = test_index.fetch_add(1);
|
||||||
if (idx >= all_tests.size()) break;
|
if (idx >= all_tests.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto& [test_suite, test_case] = all_tests[idx];
|
auto& [test_suite, test_case] = all_tests[idx];
|
||||||
int local_failed = 0;
|
int local_failed = 0;
|
||||||
|
|||||||
@@ -19,8 +19,12 @@ using xe::cpu::ppc::PPCContext;
|
|||||||
|
|
||||||
// Helper for floating-point comparison with epsilon
|
// Helper for floating-point comparison with epsilon
|
||||||
static bool ApproxEqual(double a, double b, double epsilon = 1e-6) {
|
static bool ApproxEqual(double a, double b, double epsilon = 1e-6) {
|
||||||
if (std::isnan(a) && std::isnan(b)) return true;
|
if (std::isnan(a) && std::isnan(b)) {
|
||||||
if (std::isinf(a) && std::isinf(b)) return (a > 0) == (b > 0);
|
return true;
|
||||||
|
}
|
||||||
|
if (std::isinf(a) && std::isinf(b)) {
|
||||||
|
return (a > 0) == (b > 0);
|
||||||
|
}
|
||||||
return std::abs(a - b) <= epsilon * std::max(std::abs(a), std::abs(b));
|
return std::abs(a - b) <= epsilon * std::max(std::abs(a), std::abs(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -580,7 +580,9 @@ TEST_CASE("LOAD_VECTOR_LEFT", "[memory]") {
|
|||||||
uint32_t aligned_addr = (guest_addr + 15) & ~15u;
|
uint32_t aligned_addr = (guest_addr + 15) & ~15u;
|
||||||
auto* host_ptr =
|
auto* host_ptr =
|
||||||
reinterpret_cast<uint8_t*>(test.memory->TranslateVirtual(aligned_addr));
|
reinterpret_cast<uint8_t*>(test.memory->TranslateVirtual(aligned_addr));
|
||||||
for (int i = 0; i < 16; ++i) host_ptr[i] = static_cast<uint8_t>(0x10 + i);
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
host_ptr[i] = static_cast<uint8_t>(0x10 + i);
|
||||||
|
}
|
||||||
|
|
||||||
// LVL at aligned address — should load data (not crash).
|
// LVL at aligned address — should load data (not crash).
|
||||||
test.Run([&](PPCContext* ctx) { ctx->r[4] = aligned_addr; },
|
test.Run([&](PPCContext* ctx) { ctx->r[4] = aligned_addr; },
|
||||||
@@ -604,7 +606,9 @@ TEST_CASE("LOAD_VECTOR_RIGHT", "[memory]") {
|
|||||||
uint32_t aligned_addr = (guest_addr + 15) & ~15u;
|
uint32_t aligned_addr = (guest_addr + 15) & ~15u;
|
||||||
auto* host_ptr =
|
auto* host_ptr =
|
||||||
reinterpret_cast<uint8_t*>(test.memory->TranslateVirtual(aligned_addr));
|
reinterpret_cast<uint8_t*>(test.memory->TranslateVirtual(aligned_addr));
|
||||||
for (int i = 0; i < 16; ++i) host_ptr[i] = static_cast<uint8_t>(0x20 + i);
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
host_ptr[i] = static_cast<uint8_t>(0x20 + i);
|
||||||
|
}
|
||||||
|
|
||||||
// LVR at aligned address returns zero (no bytes before alignment boundary).
|
// LVR at aligned address returns zero (no bytes before alignment boundary).
|
||||||
test.Run([&](PPCContext* ctx) { ctx->r[4] = aligned_addr; },
|
test.Run([&](PPCContext* ctx) { ctx->r[4] = aligned_addr; },
|
||||||
|
|||||||
@@ -941,8 +941,9 @@ bool XexModule::Load(const std::string_view name, const std::string_view path,
|
|||||||
// back to xex_security_info otherwise
|
// back to xex_security_info otherwise
|
||||||
base_address_ = xex_security_info()->load_address;
|
base_address_ = xex_security_info()->load_address;
|
||||||
xe::be<uint32_t>* base_addr_opt = nullptr;
|
xe::be<uint32_t>* base_addr_opt = nullptr;
|
||||||
if (GetOptHeader(XEX_HEADER_IMAGE_BASE_ADDRESS, &base_addr_opt))
|
if (GetOptHeader(XEX_HEADER_IMAGE_BASE_ADDRESS, &base_addr_opt)) {
|
||||||
base_address_ = *base_addr_opt;
|
base_address_ = *base_addr_opt;
|
||||||
|
}
|
||||||
|
|
||||||
// Setup debug info.
|
// Setup debug info.
|
||||||
name_ = name;
|
name_ = name;
|
||||||
|
|||||||
@@ -1299,11 +1299,12 @@ bool Emulator::ExceptionCallback(Exception* ex) {
|
|||||||
if (ex->code() == Exception::Code::kAccessViolation) {
|
if (ex->code() == Exception::Code::kAccessViolation) {
|
||||||
const char* op_str = "unknown";
|
const char* op_str = "unknown";
|
||||||
if (ex->access_violation_operation() ==
|
if (ex->access_violation_operation() ==
|
||||||
Exception::AccessViolationOperation::kRead)
|
Exception::AccessViolationOperation::kRead) {
|
||||||
op_str = "read";
|
op_str = "read";
|
||||||
else if (ex->access_violation_operation() ==
|
} else if (ex->access_violation_operation() ==
|
||||||
Exception::AccessViolationOperation::kWrite)
|
Exception::AccessViolationOperation::kWrite) {
|
||||||
op_str = "write";
|
op_str = "write";
|
||||||
|
}
|
||||||
crash_msg.append(fmt::format("Access Violation: {} at 0x{:016X}\n", op_str,
|
crash_msg.append(fmt::format("Access Violation: {} at 0x{:016X}\n", op_str,
|
||||||
ex->fault_address()));
|
ex->fault_address()));
|
||||||
} else if (ex->code() == Exception::Code::kIllegalInstruction) {
|
} else if (ex->code() == Exception::Code::kIllegalInstruction) {
|
||||||
|
|||||||
@@ -1141,9 +1141,15 @@ void PipelineCache::TranslateShadersForStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dxc_compiler) dxc_compiler->Release();
|
if (dxc_compiler) {
|
||||||
if (dxc_utils) dxc_utils->Release();
|
dxc_compiler->Release();
|
||||||
if (dxbc_converter) dxbc_converter->Release();
|
}
|
||||||
|
if (dxc_utils) {
|
||||||
|
dxc_utils->Release();
|
||||||
|
}
|
||||||
|
if (dxbc_converter) {
|
||||||
|
dxbc_converter->Release();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t logical_processor_count = xe::threading::logical_processor_count();
|
size_t logical_processor_count = xe::threading::logical_processor_count();
|
||||||
@@ -3260,9 +3266,15 @@ void PipelineCache::CreationThread(size_t thread_index) {
|
|||||||
}
|
}
|
||||||
if (thread_index >= creation_threads_shutdown_from_) {
|
if (thread_index >= creation_threads_shutdown_from_) {
|
||||||
// Cleanup thread-local resources.
|
// Cleanup thread-local resources.
|
||||||
if (dxc_compiler) dxc_compiler->Release();
|
if (dxc_compiler) {
|
||||||
if (dxc_utils) dxc_utils->Release();
|
dxc_compiler->Release();
|
||||||
if (dxbc_converter) dxbc_converter->Release();
|
}
|
||||||
|
if (dxc_utils) {
|
||||||
|
dxc_utils->Release();
|
||||||
|
}
|
||||||
|
if (dxbc_converter) {
|
||||||
|
dxbc_converter->Release();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
creation_request_cond_.wait(lock);
|
creation_request_cond_.wait(lock);
|
||||||
|
|||||||
@@ -154,8 +154,9 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
|||||||
|
|
||||||
// If VSYNC is enabled, but frames are not limited,
|
// If VSYNC is enabled, but frames are not limited,
|
||||||
// lock framerate at default value of 60
|
// lock framerate at default value of 60
|
||||||
if (normalized_framerate_limit == 0 && cvars::vsync)
|
if (normalized_framerate_limit == 0 && cvars::vsync) {
|
||||||
normalized_framerate_limit = 60;
|
normalized_framerate_limit = 60;
|
||||||
|
}
|
||||||
|
|
||||||
const double vsync_duration_d =
|
const double vsync_duration_d =
|
||||||
cvars::vsync
|
cvars::vsync
|
||||||
|
|||||||
@@ -467,7 +467,9 @@ void HidDemoApp::DrawInputGetKeystroke(bool poll, bool hide_repeats,
|
|||||||
for (uint32_t user_index = 0; user_index < MAX_USERS; ++user_index) {
|
for (uint32_t user_index = 0; user_index < MAX_USERS; ++user_index) {
|
||||||
DrawUserInputGetKeystroke(user_index, poll, hide_repeats, clear_log);
|
DrawUserInputGetKeystroke(user_index, poll, hide_repeats, clear_log);
|
||||||
}
|
}
|
||||||
if (tab_bar) ImGui::EndTabBar();
|
if (tab_bar) {
|
||||||
|
ImGui::EndTabBar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace hid
|
} // namespace hid
|
||||||
|
|||||||
@@ -1446,15 +1446,18 @@ void KernelState::SetProcessTLSVars(X_KPROCESS* process, int num_slots,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set remainder of bitset
|
// set remainder of bitset
|
||||||
if (((num_slots + 3) & 0x1C) != 0)
|
if (((num_slots + 3) & 0x1C) != 0) {
|
||||||
process->tls_slot_bitmap[count_div32] = -1
|
process->tls_slot_bitmap[count_div32] = -1
|
||||||
<< (32 - ((num_slots + 3) & 0x1C));
|
<< (32 - ((num_slots + 3) & 0x1C));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void AllocateThread(PPCContext* context) {
|
void AllocateThread(PPCContext* context) {
|
||||||
uint32_t thread_mem_size = static_cast<uint32_t>(context->r[3]);
|
uint32_t thread_mem_size = static_cast<uint32_t>(context->r[3]);
|
||||||
uint32_t a2 = static_cast<uint32_t>(context->r[4]);
|
uint32_t a2 = static_cast<uint32_t>(context->r[4]);
|
||||||
uint32_t a3 = static_cast<uint32_t>(context->r[5]);
|
uint32_t a3 = static_cast<uint32_t>(context->r[5]);
|
||||||
if (thread_mem_size <= 0xFD8) thread_mem_size += 8;
|
if (thread_mem_size <= 0xFD8) {
|
||||||
|
thread_mem_size += 8;
|
||||||
|
}
|
||||||
uint32_t result =
|
uint32_t result =
|
||||||
xboxkrnl::xeAllocatePoolTypeWithTag(context, thread_mem_size, a2, a3);
|
xboxkrnl::xeAllocatePoolTypeWithTag(context, thread_mem_size, a2, a3);
|
||||||
if (((unsigned short)result & 0xFFF) != 0) {
|
if (((unsigned short)result & 0xFFF) != 0) {
|
||||||
|
|||||||
@@ -589,9 +589,10 @@ void GamercardUI::OnDraw(ImGuiIO& io) {
|
|||||||
dialog_open = false;
|
dialog_open = false;
|
||||||
}
|
}
|
||||||
if (!is_valid_gamertag) {
|
if (!is_valid_gamertag) {
|
||||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) {
|
||||||
ImGui::SetTooltip("Saving disabled! Invalid gamertag provided.");
|
ImGui::SetTooltip("Saving disabled! Invalid gamertag provided.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
|||||||
@@ -524,7 +524,9 @@ dword_result_t XamShowDeviceSelectorUI_entry(
|
|||||||
// Default to the first storage device (HDD) if headless.
|
// Default to the first storage device (HDD) if headless.
|
||||||
return xeXamDispatchHeadless(
|
return xeXamDispatchHeadless(
|
||||||
[device_id_ptr, devices]() -> X_RESULT {
|
[device_id_ptr, devices]() -> X_RESULT {
|
||||||
if (devices.empty()) return X_ERROR_CANCELLED;
|
if (devices.empty()) {
|
||||||
|
return X_ERROR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
const DummyDeviceInfo* device_info = devices.front();
|
const DummyDeviceInfo* device_info = devices.front();
|
||||||
*device_id_ptr = static_cast<uint32_t>(device_info->device_id);
|
*device_id_ptr = static_cast<uint32_t>(device_info->device_id);
|
||||||
@@ -535,7 +537,9 @@ dword_result_t XamShowDeviceSelectorUI_entry(
|
|||||||
|
|
||||||
auto close = [device_id_ptr, devices](MessageBoxDialog* dialog) -> X_RESULT {
|
auto close = [device_id_ptr, devices](MessageBoxDialog* dialog) -> X_RESULT {
|
||||||
uint32_t button = dialog->chosen_button();
|
uint32_t button = dialog->chosen_button();
|
||||||
if (button >= devices.size()) return X_ERROR_CANCELLED;
|
if (button >= devices.size()) {
|
||||||
|
return X_ERROR_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
const DummyDeviceInfo* device_info = devices.at(button);
|
const DummyDeviceInfo* device_info = devices.at(button);
|
||||||
*device_id_ptr = static_cast<uint32_t>(device_info->device_id);
|
*device_id_ptr = static_cast<uint32_t>(device_info->device_id);
|
||||||
@@ -911,7 +915,9 @@ X_RESULT xeXamShowSigninUI(uint32_t user_index, uint32_t users_needed,
|
|||||||
UserProfile* profile = kernel_state()->xam_state()->GetUserProfile(i);
|
UserProfile* profile = kernel_state()->xam_state()->GetUserProfile(i);
|
||||||
if (profile) {
|
if (profile) {
|
||||||
xuids[i] = profile->xuid();
|
xuids[i] = profile->xuid();
|
||||||
if (xuids.size() >= users_needed) break;
|
if (xuids.size() >= users_needed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -388,9 +388,10 @@ DECLARE_XBOXKRNL_EXPORT1(KeSetDisableBoostThread, kThreading, kImplemented);
|
|||||||
uint32_t xeKeGetCurrentProcessType(cpu::ppc::PPCContext* context) {
|
uint32_t xeKeGetCurrentProcessType(cpu::ppc::PPCContext* context) {
|
||||||
auto pcr = context->TranslateVirtualGPR<X_KPCR*>(context->r[13]);
|
auto pcr = context->TranslateVirtualGPR<X_KPCR*>(context->r[13]);
|
||||||
|
|
||||||
if (!pcr->prcb_data.dpc_active)
|
if (!pcr->prcb_data.dpc_active) {
|
||||||
return context->TranslateVirtual(pcr->prcb_data.current_thread)
|
return context->TranslateVirtual(pcr->prcb_data.current_thread)
|
||||||
->process_type;
|
->process_type;
|
||||||
|
}
|
||||||
return pcr->processtype_value_in_dpc;
|
return pcr->processtype_value_in_dpc;
|
||||||
}
|
}
|
||||||
void xeKeSetCurrentProcessType(uint32_t type, cpu::ppc::PPCContext* context) {
|
void xeKeSetCurrentProcessType(uint32_t type, cpu::ppc::PPCContext* context) {
|
||||||
|
|||||||
@@ -32,14 +32,22 @@ static inline u128 u128_sub(u128 a, uint64_t b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline u128 u128_shl(u128 v, int s) {
|
static inline u128 u128_shl(u128 v, int s) {
|
||||||
if (s == 0) return v;
|
if (s == 0) {
|
||||||
if (s >= 64) return {0, v.lo << (s - 64)};
|
return v;
|
||||||
|
}
|
||||||
|
if (s >= 64) {
|
||||||
|
return {0, v.lo << (s - 64)};
|
||||||
|
}
|
||||||
return {v.lo << s, (v.hi << s) | (v.lo >> (64 - s))};
|
return {v.lo << s, (v.hi << s) | (v.lo >> (64 - s))};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u128 u128_shr(u128 v, int s) {
|
static inline u128 u128_shr(u128 v, int s) {
|
||||||
if (s == 0) return v;
|
if (s == 0) {
|
||||||
if (s >= 64) return {v.hi >> (s - 64), 0};
|
return v;
|
||||||
|
}
|
||||||
|
if (s >= 64) {
|
||||||
|
return {v.hi >> (s - 64), 0};
|
||||||
|
}
|
||||||
return {(v.lo >> s) | (v.hi << (64 - s)), v.hi >> s};
|
return {(v.lo >> s) | (v.hi << (64 - s)), v.hi >> s};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,8 +68,12 @@ static inline u128 u128_mul64(uint64_t a, uint64_t b) {
|
|||||||
uint64_t mid = p1 + (p0 >> 32);
|
uint64_t mid = p1 + (p0 >> 32);
|
||||||
uint64_t mid_carry = 0;
|
uint64_t mid_carry = 0;
|
||||||
uint64_t mid2 = mid + p2;
|
uint64_t mid2 = mid + p2;
|
||||||
if (mid < p1) mid_carry++;
|
if (mid < p1) {
|
||||||
if (mid2 < mid) mid_carry++;
|
mid_carry++;
|
||||||
|
}
|
||||||
|
if (mid2 < mid) {
|
||||||
|
mid_carry++;
|
||||||
|
}
|
||||||
|
|
||||||
u128 r;
|
u128 r;
|
||||||
r.lo = (mid2 << 32) | (p0 & 0xFFFFFFFF);
|
r.lo = (mid2 << 32) | (p0 & 0xFFFFFFFF);
|
||||||
@@ -98,7 +110,9 @@ static inline uint64_t u128_div64(u128 num, uint64_t den, uint64_t* rem) {
|
|||||||
|
|
||||||
// Count leading zeros - portable
|
// Count leading zeros - portable
|
||||||
static inline int clz64(uint64_t v) {
|
static inline int clz64(uint64_t v) {
|
||||||
if (v == 0) return 64;
|
if (v == 0) {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if ((v & 0xFFFFFFFF00000000ULL) == 0) {
|
if ((v & 0xFFFFFFFF00000000ULL) == 0) {
|
||||||
n += 32;
|
n += 32;
|
||||||
@@ -127,7 +141,9 @@ static inline int clz64(uint64_t v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int clz32(uint32_t v) {
|
static inline int clz32(uint32_t v) {
|
||||||
if (v == 0) return 32;
|
if (v == 0) {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if ((v & 0xFFFF0000U) == 0) {
|
if ((v & 0xFFFF0000U) == 0) {
|
||||||
n += 16;
|
n += 16;
|
||||||
@@ -193,8 +209,12 @@ class BigNum {
|
|||||||
for (size_t i = n; i > 0; i--) {
|
for (size_t i = n; i > 0; i--) {
|
||||||
uint64_t al = (i - 1 < an) ? a.limbs[i - 1] : 0;
|
uint64_t al = (i - 1 < an) ? a.limbs[i - 1] : 0;
|
||||||
uint64_t bl = (i - 1 < bn) ? b.limbs[i - 1] : 0;
|
uint64_t bl = (i - 1 < bn) ? b.limbs[i - 1] : 0;
|
||||||
if (al < bl) return -1;
|
if (al < bl) {
|
||||||
if (al > bl) return 1;
|
return -1;
|
||||||
|
}
|
||||||
|
if (al > bl) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -234,7 +254,9 @@ class BigNum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static BigNum mod(const BigNum& a, const BigNum& m) {
|
static BigNum mod(const BigNum& a, const BigNum& m) {
|
||||||
if (compare(a, m) < 0) return a;
|
if (compare(a, m) < 0) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
size_t n = m.limbs.size();
|
size_t n = m.limbs.size();
|
||||||
size_t total = a.limbs.size();
|
size_t total = a.limbs.size();
|
||||||
@@ -273,7 +295,9 @@ class BigNum {
|
|||||||
}
|
}
|
||||||
u.limbs[total] = carry;
|
u.limbs[total] = carry;
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < total; i++) u.limbs[i] = a.limbs[i];
|
for (size_t i = 0; i < total; i++) {
|
||||||
|
u.limbs[i] = a.limbs[i];
|
||||||
|
}
|
||||||
u.limbs[total] = 0;
|
u.limbs[total] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,11 +326,15 @@ class BigNum {
|
|||||||
u128 qv2 = u128_mul64(qhat_val, vn_2);
|
u128 qv2 = u128_mul64(qhat_val, vn_2);
|
||||||
u128 rhs = u128_or64(u128_shl(u128_from(rhat_val), 64), u.limbs[j - 2]);
|
u128 rhs = u128_or64(u128_shl(u128_from(rhat_val), 64), u.limbs[j - 2]);
|
||||||
bool gt = (qv2.hi > rhs.hi) || (qv2.hi == rhs.hi && qv2.lo > rhs.lo);
|
bool gt = (qv2.hi > rhs.hi) || (qv2.hi == rhs.hi && qv2.lo > rhs.lo);
|
||||||
if (!gt) break;
|
if (!gt) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
qhat_val--;
|
qhat_val--;
|
||||||
uint64_t old_rhat = rhat_val;
|
uint64_t old_rhat = rhat_val;
|
||||||
rhat_val += vn_1;
|
rhat_val += vn_1;
|
||||||
if (rhat_val < old_rhat) break;
|
if (rhat_val < old_rhat) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t carry = 0;
|
uint64_t carry = 0;
|
||||||
@@ -317,7 +345,9 @@ class BigNum {
|
|||||||
carry = prod.hi;
|
carry = prod.hi;
|
||||||
uint64_t u_val = u.limbs[j - n + i];
|
uint64_t u_val = u.limbs[j - n + i];
|
||||||
u.limbs[j - n + i] = u_val - prod_lo;
|
u.limbs[j - n + i] = u_val - prod_lo;
|
||||||
if (u_val < prod_lo) carry++;
|
if (u_val < prod_lo) {
|
||||||
|
carry++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int64_t final_diff =
|
int64_t final_diff =
|
||||||
static_cast<int64_t>(u.limbs[j]) - static_cast<int64_t>(carry);
|
static_cast<int64_t>(u.limbs[j]) - static_cast<int64_t>(carry);
|
||||||
@@ -345,7 +375,9 @@ class BigNum {
|
|||||||
carry = u.limbs[i - 1] & ((1ULL << shift) - 1);
|
carry = u.limbs[i - 1] & ((1ULL << shift) - 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < n; i++) r.limbs[i] = u.limbs[i];
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
r.limbs[i] = u.limbs[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.trim();
|
r.trim();
|
||||||
|
|||||||
@@ -293,13 +293,17 @@ class object_ref {
|
|||||||
}
|
}
|
||||||
explicit object_ref(const object_ref& right) noexcept {
|
explicit object_ref(const object_ref& right) noexcept {
|
||||||
reset(right.get());
|
reset(right.get());
|
||||||
if (value_) value_->Retain();
|
if (value_) {
|
||||||
|
value_->Retain();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
template <class V>
|
template <class V>
|
||||||
requires std::is_convertible_v<V*, T*>
|
requires std::is_convertible_v<V*, T*>
|
||||||
object_ref(const object_ref<V>& right) noexcept {
|
object_ref(const object_ref<V>& right) noexcept {
|
||||||
reset(right.get());
|
reset(right.get());
|
||||||
if (value_) value_->Retain();
|
if (value_) {
|
||||||
|
value_->Retain();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ref(object_ref&& right) noexcept : value_(right.release()) {}
|
object_ref(object_ref&& right) noexcept : value_(right.release()) {}
|
||||||
@@ -395,7 +399,9 @@ object_ref<T> make_object(Args&&... args) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
object_ref<T> retain_object(T* ptr) {
|
object_ref<T> retain_object(T* ptr) {
|
||||||
if (ptr) ptr->Retain();
|
if (ptr) {
|
||||||
|
ptr->Retain();
|
||||||
|
}
|
||||||
return object_ref<T>(ptr);
|
return object_ref<T>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -719,9 +719,13 @@ void XThread::SetPriority(int32_t increment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void XThread::CheckQuantumAndDecay() {
|
void XThread::CheckQuantumAndDecay() {
|
||||||
if (cvars::ignore_thread_priorities) return;
|
if (cvars::ignore_thread_priorities) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Real-time threads (current priority >= 0x12) don't decay on Xenon.
|
// Real-time threads (current priority >= 0x12) don't decay on Xenon.
|
||||||
if (priority_ >= 18) return;
|
if (priority_ >= 18) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t now = Clock::QueryHostUptimeMillis();
|
uint64_t now = Clock::QueryHostUptimeMillis();
|
||||||
uint64_t elapsed = now - quantum_start_ms_;
|
uint64_t elapsed = now - quantum_start_ms_;
|
||||||
@@ -731,7 +735,9 @@ void XThread::CheckQuantumAndDecay() {
|
|||||||
// effective priority by exactly 1 and resets quantum. We approximate
|
// effective priority by exactly 1 and resets quantum. We approximate
|
||||||
// this by decaying 1 priority level per 20ms of elapsed wall-clock time.
|
// this by decaying 1 priority level per 20ms of elapsed wall-clock time.
|
||||||
constexpr uint64_t kQuantumPeriodMs = 20;
|
constexpr uint64_t kQuantumPeriodMs = 20;
|
||||||
if (elapsed < kQuantumPeriodMs) return;
|
if (elapsed < kQuantumPeriodMs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t decay_steps = static_cast<int32_t>(elapsed / kQuantumPeriodMs);
|
int32_t decay_steps = static_cast<int32_t>(elapsed / kQuantumPeriodMs);
|
||||||
// On the first decay step, drain the accumulated priority boost as well.
|
// On the first decay step, drain the accumulated priority boost as well.
|
||||||
@@ -756,7 +762,9 @@ void XThread::CheckQuantumAndDecay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void XThread::BoostOnWake(int32_t increment) {
|
void XThread::BoostOnWake(int32_t increment) {
|
||||||
if (cvars::ignore_thread_priorities) return;
|
if (cvars::ignore_thread_priorities) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Real-time threads (priority >= 0x12) just get their quantum reset.
|
// Real-time threads (priority >= 0x12) just get their quantum reset.
|
||||||
if (priority_ >= 18) {
|
if (priority_ >= 18) {
|
||||||
|
|||||||
@@ -55,7 +55,9 @@ class CDialogEventHandler : public IFileDialogEvents,
|
|||||||
|
|
||||||
IFACEMETHODIMP_(ULONG) Release() {
|
IFACEMETHODIMP_(ULONG) Release() {
|
||||||
long cRef = InterlockedDecrement(&_cRef);
|
long cRef = InterlockedDecrement(&_cRef);
|
||||||
if (!cRef) delete this;
|
if (!cRef) {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
return cRef;
|
return cRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user