diff --git a/core/ir/aarch64/instr.c b/core/ir/aarch64/instr.c index 8e0d6fb7371..63a0ec57f2c 100644 --- a/core/ir/aarch64/instr.c +++ b/core/ir/aarch64/instr.c @@ -34,19 +34,21 @@ #include "../globals.h" #include "instr.h" #include "decode.h" - +#include "encode_api.h" #include "opcode_names.h" +/* XXX i#6690: currently only A64 is supported for instruction encoding. + * We want to add support for A64 decoding and synthetic ISA encoding as well. + * XXX i#1684: move this function to core/ir/instr_shared.c once we can support + * all architectures in the same build of DR. + */ bool instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode) { - return (mode == DR_ISA_ARM_A64); -} - -dr_isa_mode_t -instr_get_isa_mode(instr_t *instr) -{ - return DR_ISA_ARM_A64; + if (mode != DR_ISA_ARM_A64) + return false; + instr->isa_mode = DR_ISA_ARM_A64; + return true; } int diff --git a/core/ir/arm/instr.c b/core/ir/arm/instr.c index 7097f19045e..08c7e90014f 100644 --- a/core/ir/arm/instr.c +++ b/core/ir/arm/instr.c @@ -32,28 +32,24 @@ #include "../globals.h" #include "instr.h" +#include "encode_api.h" #include "decode.h" -/* FIXME i#1551: add A64 and Thumb support throughout */ - +/* XXX i#6690: currently only A32 and Thumb is supported for instruction encoding. + * We want to add support for A32 and Thumb decoding and synthetic ISA encoding as well. + * XXX i#1684: move this function to core/ir/instr_shared.c once we can support + * all architectures in the same build of DR. + */ bool instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode) { - if (mode == DR_ISA_ARM_THUMB) - instr->flags |= INSTR_THUMB_MODE; - else if (mode == DR_ISA_ARM_A32) - instr->flags &= ~INSTR_THUMB_MODE; - else + if (mode != DR_ISA_ARM_THUMB && mode != DR_ISA_ARM_A32) { return false; + } + instr->isa_mode = mode; return true; } -dr_isa_mode_t -instr_get_isa_mode(instr_t *instr) -{ - return TEST(INSTR_THUMB_MODE, instr->flags) ? DR_ISA_ARM_THUMB : DR_ISA_ARM_A32; -} - int instr_length_arch(dcontext_t *dcontext, instr_t *instr) { diff --git a/core/ir/instr.h b/core/ir/instr.h index b26e83017cb..76dc3a02c82 100644 --- a/core/ir/instr.h +++ b/core/ir/instr.h @@ -202,19 +202,8 @@ enum { INSTR_DO_NOT_EMIT = 0x10000000, /* PR 251479: re-relativization support: is instr->rip_rel_pos valid? */ INSTR_RIP_REL_VALID = 0x20000000, -#ifdef X86 - /* PR 278329: each instr stores its own mode */ - INSTR_X86_MODE = 0x40000000, -#elif defined(ARM) - /* We assume we don't need to distinguish A64 from A32 as you cannot swap - * between them in user mode. Thus we only need one flag. - * XXX: we might want more power for drdecode, though the global isa_mode - * should be sufficient there. - */ - INSTR_THUMB_MODE = 0x40000000, -#endif /* PR 267260: distinguish our own mangling from client-added instrs */ - INSTR_OUR_MANGLING = 0x80000000, + INSTR_OUR_MANGLING = 0x40000000, }; #define DR_TUPLE_TYPE_BITS 4 diff --git a/core/ir/instr_api.h b/core/ir/instr_api.h index 5b6017d4a88..11f05e0c6eb 100644 --- a/core/ir/instr_api.h +++ b/core/ir/instr_api.h @@ -310,6 +310,12 @@ struct _instr_t { byte num_dsts; byte num_srcs; + /* Instruction ISA mode to support multiple architectures in the same build of DR + * (xref i#6698 i#1684). + * This field holds values of type #dr_isa_mode_t. + */ + byte isa_mode; + union { struct { /* for efficiency everyone has a 1st src opnd, since we often just diff --git a/core/ir/instr_shared.c b/core/ir/instr_shared.c index 30f0f4b1aea..a3943249feb 100644 --- a/core/ir/instr_shared.c +++ b/core/ir/instr_shared.c @@ -84,16 +84,19 @@ instr_t * instr_create(void *drcontext) { + bool is_instr_isa_mode_set = false; dcontext_t *dcontext = (dcontext_t *)drcontext; instr_t *instr = (instr_t *)heap_alloc(dcontext, sizeof(instr_t) HEAPACCT(ACCT_IR)); /* everything initializes to 0, even flags, to indicate * an uninitialized instruction */ memset((void *)instr, 0, sizeof(instr_t)); #if defined(X86) && defined(X64) - instr_set_isa_mode(instr, X64_CACHE_MODE_DC(dcontext) ? DR_ISA_AMD64 : DR_ISA_IA32); -#elif defined(ARM) - instr_set_isa_mode(instr, dr_get_isa_mode(dcontext)); + is_instr_isa_mode_set = instr_set_isa_mode( + instr, X64_CACHE_MODE_DC(dcontext) ? DR_ISA_AMD64 : DR_ISA_IA32); +#else + is_instr_isa_mode_set = instr_set_isa_mode(instr, dr_get_isa_mode(dcontext)); #endif + CLIENT_ASSERT(is_instr_isa_mode_set, "setting instruction ISA mode unsuccessful"); return instr; } @@ -442,6 +445,12 @@ private_instr_encode(dcontext_t *dcontext, instr_t *instr, bool always_cache) return len; } +dr_isa_mode_t +instr_get_isa_mode(instr_t *instr) +{ + return (dr_isa_mode_t)instr->isa_mode; +} + #define inlined_instr_get_opcode(instr) \ (IF_DEBUG_(CLIENT_ASSERT(sizeof(*instr) == sizeof(instr_t), "invalid type"))( \ ((instr)->opcode == OP_UNDECODED) \ diff --git a/core/ir/riscv64/instr.c b/core/ir/riscv64/instr.c index 2a28ceece39..e35550ce62f 100644 --- a/core/ir/riscv64/instr.c +++ b/core/ir/riscv64/instr.c @@ -32,17 +32,20 @@ #include "../globals.h" #include "instr.h" +#include "encode_api.h" +/* XXX i#6690: currently only RISCV64 is supported for instruction encoding. + * We want to add support for RISCV64 decoding and synthetic ISA encoding as well. + * XXX i#1684: move this function to core/ir/instr_shared.c once we can support + * all architectures in the same build of DR. + */ bool instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode) { - return (mode == DR_ISA_RV64IMAFDC); -} - -dr_isa_mode_t -instr_get_isa_mode(instr_t *instr) -{ - return DR_ISA_RV64IMAFDC; + if (mode != DR_ISA_RV64IMAFDC) + return false; + instr->isa_mode = DR_ISA_RV64IMAFDC; + return true; } int diff --git a/core/ir/x86/instr.c b/core/ir/x86/instr.c index 9db609e7e81..b9cf49eea69 100644 --- a/core/ir/x86/instr.c +++ b/core/ir/x86/instr.c @@ -40,6 +40,7 @@ #include "instr.h" #include "decode.h" #include "decode_private.h" +#include "encode_api.h" #include "instr_create_shared.h" #ifdef X64 @@ -51,9 +52,9 @@ void instr_set_x86_mode(instr_t *instr, bool x86) { if (x86) - instr->flags |= INSTR_X86_MODE; + instr->isa_mode = DR_ISA_IA32; else - instr->flags &= ~INSTR_X86_MODE; + instr->isa_mode = DR_ISA_AMD64; } /* @@ -63,37 +64,29 @@ instr_set_x86_mode(instr_t *instr, bool x86) bool instr_get_x86_mode(instr_t *instr) { - return TEST(INSTR_X86_MODE, instr->flags); + return instr->isa_mode == DR_ISA_IA32; } #endif +/* XXX i#6690: currently only x86 and x64 are supported for instruction encoding. + * We want to add support for x86 and x64 decoding and synthetic ISA encoding as well. + * XXX i#1684: move this function to core/ir/instr_shared.c once we can support + * all architectures in the same build of DR. + */ bool instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode) { #ifdef X64 - if (mode == DR_ISA_IA32) - instr_set_x86_mode(instr, true); - else if (mode == DR_ISA_AMD64) - instr_set_x86_mode(instr, false); - else + if (mode != DR_ISA_IA32 && mode != DR_ISA_AMD64) return false; #else if (mode != DR_ISA_IA32) return false; #endif + instr->isa_mode = mode; return true; } -dr_isa_mode_t -instr_get_isa_mode(instr_t *instr) -{ -#ifdef X64 - return TEST(INSTR_X86_MODE, instr->flags) ? DR_ISA_IA32 : DR_ISA_AMD64; -#else - return DR_ISA_IA32; -#endif -} - int instr_length_arch(dcontext_t *dcontext, instr_t *instr) {