Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds ARM and AArch64 compatibility macros for the CC/VAS enums #2525

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/cs_v6_release_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ Such an instruction is ill-defined in LLVM and should be fixed upstream.

| Keyword | Change | Justification |
|---------|--------|---------------|
| `ARMCC_*` | `ARMCC_EQ == 0` but `ARMCC_INVALID != 0` | They match the LLVM enum. Better for LLVM compatibility and code generation. |
| `ARMCC_*` | `ARMCC_EQ == 0` but `ARMCC_INVALID != 0` | They match the LLVM enum. Better for LLVM compatibility and code generation. Check the compatibility option below. |
| `ARM_CC` | `ARM_CC``ARMCC` and value change | They match the same LLVM enum. Better for LLVM compatibility and code generation. |
| Post-index | Post-index memory access has the disponent now set in the `MEMORY` operand! No longer as separated `reg`/`imm` operand. | The CS memory operand had a field which was there for disponents. Not having it set, for post-index operands was inconsistent. |
| Sign `mem.disp` | `mem.disp` is now always positive and the `subtracted` flag indicates if it should be subtracted. | It was inconsistent before. |
Expand Down Expand Up @@ -358,7 +358,7 @@ Such an instruction is ill-defined in LLVM and should be fixed upstream.
| SYSZ -> SystemZ | `SYSZ` was everywhere renamed to `SystemZ` to match the LLVM naming. | See below |
| `SYSTEMZ_CC_*` | `SYSTEMZ_CC_O = 0` and `SYSTEMZ_CC_INVALID != 0` | They match the same LLVM values. Better for LLVM compatibility and code generation. |

### Notes about AArch64 and SystemZ renaming
### Notes about AArch64, SystemZ and ARM renaming

`ARM64` was everywhere renamed to `AArch64`. And `SYSZ` to `SYSTEMZ`. This is a necessity to ensure that the update scripts stay reasonably simple.
Capstone was very inconsistent with the naming before (sometimes `AArch64` sometimes `ARM64`. Sometimes `SYSZ` sometimes `SYSTEMZ`).
Expand All @@ -375,9 +375,12 @@ _Compatibility header_

If you want to use the compatibility header and stick with the `ARM64`/`SYSZ` naming, you can define `CAPSTONE_AARCH64_COMPAT_HEADER` and `CAPSTONE_SYSTEMZ_COMPAT_HEADER` before including `capstone.h`.

**Note**: The `CAPSTONE_ARM_COMPAT_HEADER` will only define macros for the `ARM_CC -> ARMCC` and `arm_cc -> ARMCC_CondCodes` renaming.

```c
#define CAPSTONE_SYSTEMZ_COMPAT_HEADER
#define CAPSTONE_AARCH64_COMPAT_HEADER
#define CAPSTONE_ARM_COMPAT_HEADER
#include <capstone/capstone.h>

// Your code...
Expand Down
20 changes: 20 additions & 0 deletions include/capstone/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1706,6 +1706,26 @@ typedef enum arm_insn_group {
ARM_GRP_ENDING,
} arm_insn_group;

#ifdef CAPSTONE_ARM_COMPAT_HEADER
#define arm_cc ARMCC_CondCodes
#define ARM_CC_EQ ARMCC_EQ
#define ARM_CC_NE ARMCC_NE
#define ARM_CC_HS ARMCC_HS
#define ARM_CC_LO ARMCC_LO
#define ARM_CC_MI ARMCC_MI
#define ARM_CC_PL ARMCC_PL
#define ARM_CC_VS ARMCC_VS
#define ARM_CC_VC ARMCC_VC
#define ARM_CC_HI ARMCC_HI
#define ARM_CC_LS ARMCC_LS
#define ARM_CC_GE ARMCC_GE
#define ARM_CC_LT ARMCC_LT
#define ARM_CC_GT ARMCC_GT
#define ARM_CC_LE ARMCC_LE
#define ARM_CC_AL ARMCC_AL
#define ARM_CC_INVALID ARMCC_Invalid
#endif

#ifdef __cplusplus
}
#endif
Expand Down
34 changes: 34 additions & 0 deletions include/capstone/arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -4576,3 +4576,37 @@ typedef enum {
#endif

#endif

#define arm64_cc AArch64CC_CondCode
#define ARM64_CC_EQ AArch64CC_EQ
#define ARM64_CC_NE AArch64CC_NE
#define ARM64_CC_HS AArch64CC_HS
#define ARM64_CC_LO AArch64CC_LO
#define ARM64_CC_MI AArch64CC_MI
#define ARM64_CC_PL AArch64CC_PL
#define ARM64_CC_VS AArch64CC_VS
#define ARM64_CC_VC AArch64CC_VC
#define ARM64_CC_HI AArch64CC_HI
#define ARM64_CC_LS AArch64CC_LS
#define ARM64_CC_GE AArch64CC_GE
#define ARM64_CC_LT AArch64CC_LT
#define ARM64_CC_GT AArch64CC_GT
#define ARM64_CC_LE AArch64CC_LE
#define ARM64_CC_AL AArch64CC_AL
#define ARM64_CC_INVALID AArch64CC_Invalid
#define ARM64_VAS_INVALID AARCH64LAYOUT_VL_INVALID
#define ARM64_VAS_16B AARCH64LAYOUT_VL_16B
#define ARM64_VAS_8B AARCH64LAYOUT_VL_8B
#define ARM64_VAS_4B AARCH64LAYOUT_VL_4B
#define ARM64_VAS_1B AARCH64LAYOUT_VL_1B
#define ARM64_VAS_8H AARCH64LAYOUT_VL_8H
#define ARM64_VAS_4H AARCH64LAYOUT_VL_4H
#define ARM64_VAS_2H AARCH64LAYOUT_VL_2H
#define ARM64_VAS_1H AARCH64LAYOUT_VL_1H
#define ARM64_VAS_4S AARCH64LAYOUT_VL_4S
#define ARM64_VAS_2S AARCH64LAYOUT_VL_2S
#define ARM64_VAS_1S AARCH64LAYOUT_VL_1S
#define ARM64_VAS_2D AARCH64LAYOUT_VL_2D
#define ARM64_VAS_1D AARCH64LAYOUT_VL_1D
#define ARM64_VAS_1Q AARCH64LAYOUT_VL_1Q
#define arm64_vas AArch64Layout_VectorLayout
43 changes: 43 additions & 0 deletions suite/auto-sync/src/autosync/HeaderPatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,43 @@

from pathlib import Path

AARCH64_CC_MACROS = [
"\n",
"#define arm64_cc AArch64CC_CondCode\n",
"#define ARM64_CC_EQ AArch64CC_EQ\n",
"#define ARM64_CC_NE AArch64CC_NE\n",
"#define ARM64_CC_HS AArch64CC_HS\n",
"#define ARM64_CC_LO AArch64CC_LO\n",
"#define ARM64_CC_MI AArch64CC_MI\n",
"#define ARM64_CC_PL AArch64CC_PL\n",
"#define ARM64_CC_VS AArch64CC_VS\n",
"#define ARM64_CC_VC AArch64CC_VC\n",
"#define ARM64_CC_HI AArch64CC_HI\n",
"#define ARM64_CC_LS AArch64CC_LS\n",
"#define ARM64_CC_GE AArch64CC_GE\n",
"#define ARM64_CC_LT AArch64CC_LT\n",
"#define ARM64_CC_GT AArch64CC_GT\n",
"#define ARM64_CC_LE AArch64CC_LE\n",
"#define ARM64_CC_AL AArch64CC_AL\n",
"#define ARM64_CC_INVALID AArch64CC_Invalid\n",
"#define ARM64_VAS_INVALID AARCH64LAYOUT_VL_INVALID\n",
"#define ARM64_VAS_16B AARCH64LAYOUT_VL_16B\n",
"#define ARM64_VAS_8B AARCH64LAYOUT_VL_8B\n",
"#define ARM64_VAS_4B AARCH64LAYOUT_VL_4B\n",
"#define ARM64_VAS_1B AARCH64LAYOUT_VL_1B\n",
"#define ARM64_VAS_8H AARCH64LAYOUT_VL_8H\n",
"#define ARM64_VAS_4H AARCH64LAYOUT_VL_4H\n",
"#define ARM64_VAS_2H AARCH64LAYOUT_VL_2H\n",
"#define ARM64_VAS_1H AARCH64LAYOUT_VL_1H\n",
"#define ARM64_VAS_4S AARCH64LAYOUT_VL_4S\n",
"#define ARM64_VAS_2S AARCH64LAYOUT_VL_2S\n",
"#define ARM64_VAS_1S AARCH64LAYOUT_VL_1S\n",
"#define ARM64_VAS_2D AARCH64LAYOUT_VL_2D\n",
"#define ARM64_VAS_1D AARCH64LAYOUT_VL_1D\n",
"#define ARM64_VAS_1Q AARCH64LAYOUT_VL_1Q\n",
"#define arm64_vas AArch64Layout_VectorLayout\n",
]


def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -259,6 +296,10 @@ def inject_v6_header(self, v6_lines: list[str]) -> list[str]:
output.append(line)
return output

def add_cc_macros(self, v6_lines: list[str]) -> list[str]:
v6_lines += AARCH64_CC_MACROS
return v6_lines

def generate_v5_compat_header(self) -> bool:
"""
Translates the aarch64.h header into the arm64.h header and renames all aarch64 occurrences.
Expand All @@ -275,6 +316,8 @@ def generate_v5_compat_header(self) -> bool:
patched = self.replace_v6_prefix(patched)
patched = self.replace_include_guards(patched)
patched = self.inject_v6_header(patched)
if self.v6_lower == "aarch64":
patched = self.add_cc_macros(patched)

with open(self.v5, "w+") as f:
f.writelines(patched)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdio.h>
#include <inttypes.h>

#define CAPSTONE_ARM_COMPAT_HEADER
#define CAPSTONE_AARCH64_COMPAT_HEADER
#include <capstone/capstone.h>

Expand Down Expand Up @@ -55,6 +56,12 @@ int arm64(void)
fprintf(stderr, "Immediate wrong.\n");
goto err;
}
arm64_cc test_cc64 = insn[0].detail->arm64.cc + ARM64_CC_GE;
arm_cc test_cc = insn[0].detail->arm.cc + ARM_CC_LE;
printf("test_cc64 = %" PRId32 " test_cc = %" PRId32 "\n", test_cc64, test_cc);

arm64_vas test_vas = insn[0].detail->arm64.operands[0].vas + ARM64_VAS_16B;
printf("test_vas = %" PRId32 "\n", test_vas);

cs_free(insn, count);
cs_close(&handle);
Expand Down
Loading