From bd75b4f286d511e11fff150d239bbd6e685665c0 Mon Sep 17 00:00:00 2001 From: XIN <35714148+yjxxin@users.noreply.github.com> Date: Wed, 24 Nov 2021 22:36:00 +0800 Subject: [PATCH] add KMOW (#561) * add KMOW * add KMOVW * bug fix * bug fix Co-authored-by: yangjiaxin --- generated/Arch/X86/SaveState.S | 11 +++++ include/remill/Arch/X86/Runtime/State.h | 10 ++++- lib/Arch/X86/Arch.cpp | 11 +++++ lib/Arch/X86/Semantics/DATAXFER.cpp | 16 ++++++++ lib/BC/DeadStoreEliminator.cpp | 2 +- tests/X86/DATAXFER/KMOVW.S | 54 +++++++++++++++++++++++++ tests/X86/Tests.S | 2 + 7 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 tests/X86/DATAXFER/KMOVW.S diff --git a/generated/Arch/X86/SaveState.S b/generated/Arch/X86/SaveState.S index 665c98c4..0912a025 100644 --- a/generated/Arch/X86/SaveState.S +++ b/generated/Arch/X86/SaveState.S @@ -235,3 +235,14 @@ movdqu [RIP + STATE_PTR + 1872], XMM29 movdqu [RIP + STATE_PTR + 1936], XMM30 movdqu [RIP + STATE_PTR + 2000], XMM31 #endif // HAS_FEATURE_AVX512 +#if HAS_FEATURE_AVX512 +kmovq [RIP + STATE_PTR + 3512], K0 +kmovq [RIP + STATE_PTR + 3528], K1 +kmovq [RIP + STATE_PTR + 3544], K2 +kmovq [RIP + STATE_PTR + 3560], K3 +kmovq [RIP + STATE_PTR + 3576], K4 +kmovq [RIP + STATE_PTR + 3592], K5 +kmovq [RIP + STATE_PTR + 3608], K6 +kmovq [RIP + STATE_PTR + 3624], K7 + +#endif // HAS_FEATURE_AVX512 \ No newline at end of file diff --git a/include/remill/Arch/X86/Runtime/State.h b/include/remill/Arch/X86/Runtime/State.h index bbb26ad2..4dfa621d 100644 --- a/include/remill/Arch/X86/Runtime/State.h +++ b/include/remill/Arch/X86/Runtime/State.h @@ -754,6 +754,13 @@ struct alignas(8) MMX final { } __attribute__((packed)) elems[8]; }; +struct alignas(8) K_REG final { + struct alignas(8) { + uint64_t _0; + uint64_t val; + } __attribute__((packed)) elems[8]; +}; + static_assert(128 == sizeof(MMX), "Invalid structure packing of `MMX`."); enum : size_t { kNumVecRegisters = 32 }; @@ -779,9 +786,10 @@ struct alignas(16) X86State : public ArchState { XCR0 xcr0; // 8 bytes. FPU x87; // 512 bytes SegmentCaches seg_caches; // 96 bytes + K_REG k_reg; // 128 bytes. } __attribute__((packed)); -static_assert((96 + 3264 + 16) == sizeof(X86State), +static_assert((96 + 3264 + 16 + 128) == sizeof(X86State), "Invalid packing of `struct State`"); struct State : public X86State {}; diff --git a/lib/Arch/X86/Arch.cpp b/lib/Arch/X86/Arch.cpp index 22917283..7d2f0d14 100644 --- a/lib/Arch/X86/Arch.cpp +++ b/lib/Arch/X86/Arch.cpp @@ -1688,6 +1688,17 @@ void X86Arch::PopulateRegisterTable(void) const { REG(MM6, mmx.elems[6].val.qwords.elems[0], u64); REG(MM7, mmx.elems[7].val.qwords.elems[0], u64); + if (has_avx512) { + REG(K0, k_reg.elems[0].val, u64); + REG(K1, k_reg.elems[1].val, u64); + REG(K2, k_reg.elems[2].val, u64); + REG(K3, k_reg.elems[3].val, u64); + REG(K4, k_reg.elems[4].val, u64); + REG(K5, k_reg.elems[5].val, u64); + REG(K6, k_reg.elems[6].val, u64); + REG(K7, k_reg.elems[7].val, u64); + } + // Arithmetic flags. Data-flow analyses will clear these out ;-) REG(AF, aflag.af, u8); REG(CF, aflag.cf, u8); diff --git a/lib/Arch/X86/Semantics/DATAXFER.cpp b/lib/Arch/X86/Semantics/DATAXFER.cpp index dfe63897..5a249ec0 100644 --- a/lib/Arch/X86/Semantics/DATAXFER.cpp +++ b/lib/Arch/X86/Semantics/DATAXFER.cpp @@ -1121,3 +1121,19 @@ IF_64BIT(DEF_ISEL(MOVSXD_GPRv_MEMd_64) = MOVSX;) IF_64BIT(DEF_ISEL(MOVSXD_GPRv_MEMz_64) = MOVSX;) IF_64BIT(DEF_ISEL(MOVSXD_GPRv_GPR32_64) = MOVSX;) IF_64BIT(DEF_ISEL(MOVSXD_GPRv_GPRz_64) = MOVSX;) + +namespace { +template +DEF_SEM(KMOVW, S1 dst, S2 src) { + auto value = UInt16(Read(src)); + WriteZExt(dst, value); + return memory; +} + +} // namespace + +DEF_ISEL(KMOVW_MASKmskw_MASKu16_AVX512) = KMOVW; +DEF_ISEL(KMOVW_GPR32u32_MASKmskw_AVX512) = KMOVW; +DEF_ISEL(KMOVW_MASKmskw_GPR32u32_AVX512) = KMOVW; +DEF_ISEL(KMOVW_MASKmskw_MEMu16_AVX512) = KMOVW; +DEF_ISEL(KMOVW_MEMu16_MASKmskw_AVX512) = KMOVW; \ No newline at end of file diff --git a/lib/BC/DeadStoreEliminator.cpp b/lib/BC/DeadStoreEliminator.cpp index 48a42f18..6fb243a5 100644 --- a/lib/BC/DeadStoreEliminator.cpp +++ b/lib/BC/DeadStoreEliminator.cpp @@ -65,7 +65,7 @@ DEFINE_bool(name_register_variables, false, namespace remill { namespace { -static constexpr size_t kMaxNumSlots = 256; +static constexpr size_t kMaxNumSlots = 272; using ValueToOffset = std::unordered_map; using InstToOffset = std::unordered_map; diff --git a/tests/X86/DATAXFER/KMOVW.S b/tests/X86/DATAXFER/KMOVW.S new file mode 100644 index 00000000..0b8e5072 --- /dev/null +++ b/tests/X86/DATAXFER/KMOVW.S @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if HAS_FEATURE_AVX512 +TEST_BEGIN_64(KMOVW_MASKmskw_GPR32u32_AVX512, 1) +TEST_INPUTS( + 0, + 1, + 0x41, + 0xff, + 0x80) + + kmovw k2, ARG1_32 +TEST_END_64 + + +TEST_BEGIN_64(KMOVW_MASKmskw_MASKu16_AVX512, 1) +TEST_INPUTS( + 0, + 1, + 0x41, + 0xff, + 0x80) + + kmovw k2, ARG1_32 + kmovw k2, k1 +TEST_END_64 + +TEST_BEGIN_64(KMOVW_GPR32u32_MASKmskw_AVX512, 1) +TEST_INPUTS( + 0, + 1, + 0x41, + 0xff, + 0x80) + + kmovw k2, ARG1_32 + kmovw RET_32, k2 +TEST_END_64 + +#endif // HAS_FEATURE_AVX512s \ No newline at end of file diff --git a/tests/X86/Tests.S b/tests/X86/Tests.S index d5cd8f12..a00be489 100644 --- a/tests/X86/Tests.S +++ b/tests/X86/Tests.S @@ -328,6 +328,7 @@ SYMBOL(__x86_test_table_begin): #include "tests/X86/ABI.S" #include "tests/X86/MMX/INPUTS.S" + /* Change to `0` and put new `#include`s above when making new tests to speed * up compile and test times. */ #if 1 @@ -356,6 +357,7 @@ SYMBOL(__x86_test_table_begin): #include "tests/X86/DATAXFER/MOVUPS.S" #include "tests/X86/DATAXFER/MOVZX.S" #include "tests/X86/DATAXFER/XCHG.S" +#include "tests/X86/DATAXFER/KMOVW.S" /* Bring in the rest of the semantic tests. */