aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhairul Azhar Kasmiran <kazarmy@gmail.com>2024-01-24 11:08:25 +0800
committerGitHub <noreply@github.com>2024-01-24 11:08:25 +0800
commitcb2b87974d6bdc347578eddea4558802bb6a0c1b (patch)
tree73c32d168a3f4d8c5405971d078e5ad612a64b98
parenteaf6d7ab67e506941a9c8883ab802fa168f8f3d7 (diff)
downloadcapstone-cb2b87974d6bdc347578eddea4558802bb6a0c1b.tar.gz
auto-sync BitCastStdArray.py: Transform to `union` instead (#2257)
* auto-sync BitCastStdArray.py: Transform to `union` instead * Do `typeof` manually for MSVC
-rw-r--r--arch/AArch64/AArch64AddressingModes.h33
-rw-r--r--suite/auto-sync/Updater/CppTranslator/Patches/BitCastStdArray.py20
2 files changed, 41 insertions, 12 deletions
diff --git a/arch/AArch64/AArch64AddressingModes.h b/arch/AArch64/AArch64AddressingModes.h
index 5d342a89..27029d8c 100644
--- a/arch/AArch64/AArch64AddressingModes.h
+++ b/arch/AArch64/AArch64AddressingModes.h
@@ -827,12 +827,12 @@ static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType12(uint8_t Imm)
#define DEFINE_isSVEMaskOfIdenticalElements(T) \
static inline bool CONCAT(AArch64_AM_isSVEMaskOfIdenticalElements, T)(int64_t Imm) \
{ \
- union { \
- uint64_t L; \
- T A[sizeof(int64_t) / sizeof(T)]; \
- } U; \
- U.L = Imm; \
- T *Parts = U.A; \
+ union { \
+ int64_t In; \
+ T Out[sizeof(int64_t) / sizeof(T)]; \
+ } U_Parts; \
+ U_Parts.In = Imm; \
+ T *Parts = U_Parts.Out; \
for (int i = 0; i < (sizeof(int64_t) / sizeof(T)); i++) { \
if (Parts[i] != Parts[0]) \
return false; \
@@ -887,9 +887,24 @@ AArch64_AM_isSVEMoveMaskPreferredLogicalImmediate(int64_t Imm)
if (isSVECpyImm64(Imm))
return false;
- int32_t *S = (int32_t *)(&(Imm)); // arr len = 2
- int16_t *H = (int16_t *)(&(Imm)); // arr len = 4
- int8_t *B = (int8_t *)(&(Imm)); // arr len = 8
+ union {
+ int64_t In;
+ int32_t Out[2];
+ } U_S;
+ U_S.In = Imm;
+ int32_t *S = U_S.Out;
+ union {
+ int64_t In;
+ int16_t Out[4];
+ } U_H;
+ U_H.In = Imm;
+ int16_t *H = U_H.Out;
+ union {
+ int64_t In;
+ int8_t Out[8];
+ } U_B;
+ U_B.In = Imm;
+ int8_t *B = U_B.Out;
if (CONCAT(AArch64_AM_isSVEMaskOfIdenticalElements, int32_t)(Imm) &&
isSVECpyImm32(S[0]))
diff --git a/suite/auto-sync/Updater/CppTranslator/Patches/BitCastStdArray.py b/suite/auto-sync/Updater/CppTranslator/Patches/BitCastStdArray.py
index a2c79fab..0a41c882 100644
--- a/suite/auto-sync/Updater/CppTranslator/Patches/BitCastStdArray.py
+++ b/suite/auto-sync/Updater/CppTranslator/Patches/BitCastStdArray.py
@@ -7,7 +7,14 @@ from CppTranslator.Patches.Patch import Patch
class BitCastStdArray(Patch):
"""
Patch auto S = bit_cast<std::array<int32_t, 2>>(Imm);
- to int32_t *S = ((int32_t *)(&Imm)); // Array length = 2
+ to union {
+ typeof(Imm) In;
+ int32_t Out[2];
+ } U_S;
+ U_S.In = Imm;
+ int32_t *S = U_S.Out;
+
+ MSVC doesn't support typeof so it has to be resolved manually.
"""
def __init__(self, priority: int):
@@ -38,8 +45,15 @@ class BitCastStdArray(Patch):
def get_patch(self, captures: [(Node, str)], src: bytes, **kwargs) -> bytes:
arr_name: bytes = captures[1][0].text
array_type: Node = captures[3][0]
- cast_target: bytes = captures[4][0].text
+ cast_target: bytes = captures[4][0].text.strip(b"()")
array_templ_args: bytes = array_type.named_children[0].named_children[1].named_children[1].text.strip(b"<>")
arr_type = array_templ_args.split(b",")[0]
arr_len = array_templ_args.split(b",")[1]
- return arr_type + b" *" + arr_name + b" = (" + arr_type + b"*)(&" + cast_target + b"); // arr len = " + arr_len
+ return (
+ b"union {\n"
+ + b" typeof(" + cast_target + b") In;\n"
+ + b" " + arr_type + b" Out[" + arr_len + b"];\n"
+ + b"} U_" + arr_name + b";\n"
+ + b"U_" + arr_name + b".In = " + cast_target + b";\n"
+ + arr_type + b" *" + arr_name + b" = U_" + arr_name + b".Out;"
+ )