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

i#6662 public traces, part 1: synthetic ISA #6691

Merged
merged 95 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from 85 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
f9bebe0
i#6662 synthetic ISA: encoding
edeiana Feb 28, 2024
4b70a9d
Forgot to include encode header for synthetic ISA.
edeiana Feb 28, 2024
d301f3e
Added synthetic encoding header to CMakeList.
edeiana Feb 29, 2024
a0bbf6f
Added initial implementation of synthetic encoding/decoding.
edeiana Mar 6, 2024
8b29dcc
Using x86 encode/decode for synthetic encoding/decoding
edeiana Mar 6, 2024
d2115e6
Added test for synthetic encoding/decoding.
edeiana Mar 6, 2024
44c4c3c
Merge branch 'master' into i6662-synthetic-isa
edeiana Mar 6, 2024
246003c
Added encoding/deconding of operands, although virtual registers
edeiana Mar 15, 2024
85ac64d
Fixed description of synthetic ISA mode.
edeiana Mar 15, 2024
79b736b
Updated uses of spelled out DR_ISA_SYNTHETIC.
edeiana Mar 15, 2024
9e67807
Merge remote-tracking branch 'origin/master' into i6662-synthetic-isa
edeiana Mar 15, 2024
1e8a686
Updated synthetic ISA enum use.
edeiana Mar 15, 2024
8bc947a
Updated test for synthetic ISA encoding/decoding.
edeiana Mar 15, 2024
df82fcf
Now returning next instruction's PC after synthetic ISA
edeiana Mar 15, 2024
21e8d77
Improved description in comment.
edeiana Mar 15, 2024
b3cac08
Fixed building error.
edeiana Mar 15, 2024
89e80d7
clang-format.
edeiana Mar 15, 2024
b4b1fd8
Addressed memory alignment, eflags, constants, description of encoding.
edeiana Mar 18, 2024
8df36c1
Fixed minosr issue in Synthetic ISA test: merged lines.
edeiana Mar 18, 2024
dc5f750
Setting instr_t length according to the size of the synthetic
edeiana Mar 20, 2024
8400177
Now considering registers in destination operands that are memory
edeiana Mar 20, 2024
d346c27
Improved test.
edeiana Mar 20, 2024
8d63bbf
Check for instr_t synthetic ISA moved to instr_encode()
edeiana Mar 20, 2024
4787fad
We want to minimize the impact of synthetic ISA.
edeiana Mar 20, 2024
978ed90
Now setting arithetic, operand, and raw bits flags valid after decoding.
edeiana Mar 20, 2024
efc6cf2
We don't need to temporarly change instr_t ISA mode to retrieve flags
edeiana Mar 20, 2024
46bacdb
Documented that we use instr_t ISA mode for decoding when
edeiana Mar 20, 2024
9c96008
Now checking flags, instr length, and PC.
edeiana Mar 20, 2024
615d55f
Fixed "warning C4018: '<': signed/unsigned mismatch" treated
edeiana Mar 20, 2024
df3c68d
Fixed __attribute__ extention not supported by our windows compiler.
edeiana Mar 20, 2024
dd5a979
Whoops, forgot to zero-out the first 4 bytes before encoding.
edeiana Mar 20, 2024
d4f1b3e
Improved comments.
edeiana Mar 21, 2024
7a95872
Now using dcontext ISA mode for decoding in x86.
edeiana Mar 21, 2024
806a72c
Moved encode_to_synth() from instr_encode() to instr_encode_to_copy().
edeiana Mar 21, 2024
e13b25b
Using local variable for header bytes of encoding, instead of
edeiana Mar 21, 2024
ef8560c
Improved description.
edeiana Mar 21, 2024
ab65804
Addressed PR comments.
edeiana Mar 21, 2024
b1bd6d5
Fixed grammar.
edeiana Mar 21, 2024
23995d3
Added decode_from_synth() into decode() of every architecture.
edeiana Mar 22, 2024
b1f844a
Removed synthetic ISA related tests from ir_x86.c set of tests.
edeiana Mar 22, 2024
ce3c5e1
Fixed AARCH64 and RISCV64 tests.
edeiana Mar 22, 2024
0e318dd
Added DR_ISA_SYNTHETIC to is_isa_mode_legal() for all arches.
edeiana Mar 22, 2024
224fadf
Removed decode_from_synth() from decode_from_copy(), we only want it in
edeiana Mar 22, 2024
ddf7b10
Now allowing DR_ISA_SYNTHETIC for all arches in instr_set_isa_mode().
edeiana Mar 22, 2024
363ef2e
Fixed ARM 32 test.
edeiana Mar 22, 2024
c29f344
Addressed misc (mostly minor) review comments.
edeiana Mar 23, 2024
1a2a6b1
Mapping sub-registers to their canonical register (i.e., the largest …
edeiana Mar 24, 2024
035d014
Fixed register size encoding.
edeiana Mar 24, 2024
6d4d4cf
Check if src or dst operands are present before looping through
edeiana Mar 24, 2024
96133f8
Biggest encoded synthetis instruction is now 20 bytes.
edeiana Mar 24, 2024
91981df
Fixed offset when encoding/decoding src operands.
edeiana Mar 24, 2024
bc22a59
Moved decode_from_synth() from decode() to decode_common() for all
edeiana Mar 26, 2024
2856ab0
Now we only have a single operation size field (1 byte encoding).
edeiana Mar 26, 2024
70f6942
Fix building errors for aarch64 and riscv64.
edeiana Mar 26, 2024
4caf3aa
Fix failure on AARCH64.
edeiana Mar 27, 2024
9bc4a80
Fix building error (typo).
edeiana Mar 27, 2024
f88f9b2
Renamed DR_ISA_SYNTHETIC to DR_ISA_REGDEPS.
edeiana Mar 27, 2024
a9ff2d5
Forgot one DR_ISA_SYNTHETIC in aarch64. Fixed.
edeiana Mar 27, 2024
5cd8856
Added instr_convert_to_isa_regdeps() API to translate an instr_t
edeiana Mar 29, 2024
cc34ec5
Added new API to release doc.
edeiana Mar 29, 2024
87d60ab
Updated tests.
edeiana Mar 29, 2024
ef7554c
Minor cleanup.
edeiana Mar 29, 2024
9e7c7f8
Merge branch 'master' into i6662-synthetic-isa
edeiana Mar 29, 2024
3d0106f
clang-format-14 run.
edeiana Mar 29, 2024
4553779
Fixed warning as error on windows.
edeiana Mar 29, 2024
55f737c
Added #mem_ops (i.e., loads + stores) to encoding.
edeiana Mar 31, 2024
f05c367
Added a couple more x86 instructions to test with implicit
edeiana Mar 31, 2024
2374332
Increased size of array containing encoding to max encoding size of 16
edeiana Mar 31, 2024
1b01ed5
Reverted back to no #mem_ops.
edeiana Apr 2, 2024
28b779a
Added DR_ISA_REGDEPS description.
edeiana Apr 4, 2024
c284c6b
Changed convert_to_isa_regdeps() signature.
edeiana Apr 4, 2024
9d785e1
Removed unnecessary cast to (void *).
edeiana Apr 4, 2024
a7149e9
Renaming: from synthetic to isa_regdeps.
edeiana Apr 5, 2024
547d39b
Renaming: encoding/decoding functions using isa_regdeps name.
edeiana Apr 5, 2024
2a0ada8
Added operation_size, modified encoding/decoding accordingly.
edeiana Apr 6, 2024
0b58ad7
Improved description of encoding scheme and its readability.
edeiana Apr 6, 2024
e67df8a
Improved test.
edeiana Apr 6, 2024
d41e21e
Updated documentation.
edeiana Apr 7, 2024
8db9a06
Fixed typo in documentation.
edeiana Apr 7, 2024
4615d17
clang-format-14 run.
edeiana Apr 7, 2024
8d08c07
clang-format-14 run, again.
edeiana Apr 7, 2024
cefaba5
Added encode + decode of instructions generated by INSTR_CREATE_.
edeiana Apr 7, 2024
2b0ad5e
Removed INSTR_CREATE_adr from tests for aarch64 because of i#4847.
edeiana Apr 7, 2024
d125010
Removed setting of instr_t.length, we don't use it anymore,
edeiana Apr 7, 2024
be82357
Updated test's expected output.
edeiana Apr 7, 2024
e639309
Added instr_encode_common() with is now the common routine interposed
edeiana Apr 8, 2024
b29d8a1
Added valid encoding to bytes field of instr_t when converting and
edeiana Apr 9, 2024
74c681f
Formatting fixed.
edeiana Apr 9, 2024
b931392
Addressed PR feedback.
edeiana Apr 9, 2024
1340b90
Fromatting fixed.
edeiana Apr 9, 2024
0d57ec9
Removed unnecessary header.
edeiana Apr 9, 2024
1c828b8
Improved comments and code documentation (doxygen).
edeiana Apr 9, 2024
5ad7405
Merge branch 'master' into i6662-synthetic-isa
edeiana Apr 9, 2024
2aad8e0
Fixed doxygen. Cannot reference #DR_ISA_REGDEPS in a pre-comment for
edeiana Apr 9, 2024
01ef05c
Trying to fix doxygen.
edeiana Apr 10, 2024
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
4 changes: 4 additions & 0 deletions api/docs/release.dox
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ Further non-compatibility-affecting changes include:
is set to true by default to match the existing behavior of the invariant checker.
edeiana marked this conversation as resolved.
Show resolved Hide resolved
edeiana marked this conversation as resolved.
Show resolved Hide resolved
edeiana marked this conversation as resolved.
Show resolved Hide resolved
- Added a new instr API instr_is_xrstor() that tells whether an instruction is any
variant of the x86 xrstor opcode.
- Added a new #dr_isa_mode_t: #DR_ISA_REGDEPS, which is a synthetic ISA with the main
purpose of preserving register dependencies.
- Added instr_convert_to_isa_regdeps() API that converts an #instr_t from a real ISA
edeiana marked this conversation as resolved.
Show resolved Hide resolved
(e.g., #DR_ISA_AMD64) to the #DR_ISA_REGDEPS synthetic ISA.

**************************************************
<hr>
Expand Down
2 changes: 2 additions & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ set(DECODER_SRCS
ir/${ARCH_NAME}/decode.c
ir/encode_shared.c
ir/${ARCH_NAME}/encode.c
ir/isa_regdeps/encode.c
ir/isa_regdeps/decode.c
ir/disassemble_shared.c
ir/${ARCH_NAME}/disassemble.c
ir/ir_utils_shared.c
Expand Down
10 changes: 10 additions & 0 deletions core/ir/aarch64/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@

#include <stdint.h>
#include "../globals.h"
#include "../isa_regdeps/decode.h"
#include "arch.h"
#include "decode.h"
#include "disassemble.h"
#include "encode_api.h"
#include "instr.h"
#include "instr_create_shared.h"

Expand Down Expand Up @@ -9717,6 +9719,14 @@ decode_category(uint encoding, instr_t *instr)
byte *
decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr)
{
/* #DR_ISA_REGDEPS synthetic ISA has its own decoder.
* XXX i#1684: when DR can be built with full dynamic architecture selection we won't
* need to pollute the decoding of other architectures with this synthetic ISA special
* case.
*/
if (dr_get_isa_mode(dcontext) == DR_ISA_REGDEPS)
return decode_isa_regdeps(dcontext, pc, instr);

byte *next_pc = pc + 4;
uint enc = *(uint *)pc;
uint eflags = 0;
Expand Down
3 changes: 2 additions & 1 deletion core/ir/aarch64/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/

#include "../globals.h"
#include "encode_api.h"
#include "instr.h"
#include "decode.h"
#include "decode_fast.h" /* ensure we export decode_next_pc, decode_sizeof */
Expand All @@ -41,7 +42,7 @@
bool
is_isa_mode_legal(dr_isa_mode_t mode)
{
return (mode == DR_ISA_ARM_A64);
return (mode == DR_ISA_ARM_A64 || mode == DR_ISA_REGDEPS);
}

app_pc
Expand Down
4 changes: 2 additions & 2 deletions core/ir/aarch64/instr.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
bool
instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode)
{
if (mode != DR_ISA_ARM_A64)
if (mode != DR_ISA_ARM_A64 && mode != DR_ISA_REGDEPS)
return false;
instr->isa_mode = DR_ISA_ARM_A64;
instr->isa_mode = mode;
return true;
}

Expand Down
12 changes: 11 additions & 1 deletion core/ir/arm/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
*/

#include "../globals.h"
#include "../isa_regdeps/decode.h"
#include "encode_api.h"
#include "instr.h"
#include "decode.h"
#include "decode_private.h"
Expand Down Expand Up @@ -172,7 +174,7 @@ decode_in_it_block(decode_state_t *state, app_pc pc, decode_info_t *di)
bool
is_isa_mode_legal(dr_isa_mode_t mode)
{
return (mode == DR_ISA_ARM_THUMB || DR_ISA_ARM_A32);
edeiana marked this conversation as resolved.
Show resolved Hide resolved
return (mode == DR_ISA_ARM_THUMB || mode == DR_ISA_ARM_A32 || mode == DR_ISA_REGDEPS);
}

/* We need to call canonicalize_pc_target() on all next_tag-writing
Expand Down Expand Up @@ -2428,6 +2430,14 @@ decode_opcode(dcontext_t *dcontext, byte *pc, instr_t *instr)
static byte *
decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr)
{
/* #DR_ISA_REGDEPS synthetic ISA has its own decoder.
* XXX i#1684: when DR can be built with full dynamic architecture selection we won't
* need to pollute the decoding of other architectures with this synthetic ISA special
* case.
*/
if (dr_get_isa_mode(dcontext) == DR_ISA_REGDEPS)
return decode_isa_regdeps(dcontext, pc, instr);

const instr_info_t *info = &invalid_instr;
decode_info_t di;
byte *next_pc;
Expand Down
2 changes: 1 addition & 1 deletion core/ir/arm/instr.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
bool
instr_set_isa_mode(instr_t *instr, dr_isa_mode_t mode)
{
if (mode != DR_ISA_ARM_THUMB && mode != DR_ISA_ARM_A32) {
if (mode != DR_ISA_ARM_THUMB && mode != DR_ISA_ARM_A32 && mode != DR_ISA_REGDEPS) {
return false;
}
instr->isa_mode = mode;
Expand Down
32 changes: 32 additions & 0 deletions core/ir/encode_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,38 @@ typedef enum _dr_isa_mode_t {
DR_ISA_ARM_THUMB, /**< Thumb (ARM T32). */
DR_ISA_ARM_A64, /**< ARM A64 (AArch64). */
DR_ISA_RV64IMAFDC, /**< RISC-V (rv64imafdc). */
DR_ISA_REGDEPS,
/**<
edeiana marked this conversation as resolved.
Show resolved Hide resolved
* This is a synthetic ISA that has the purpose of preserving register dependencies
* and giving hints on the type of operations each instruction is performing.
*
* For this reason the majority of operations that would normally work on instructions
* coming from an actual ISA (e.g., #DR_ISA_AMD64) are not supported.
*
* Currently we support:
* - instr_convert_to_isa_regdeps(), which converts an #instr_t of an actual ISA to a
* #DR_ISA_REGDEPS instruction;
* - instr_encode() and instr_encode_to_copy(), to encode a #DR_ISA_REGDEPS #instr_t
* into a sequence of contiguous bytes;
* - decode() and decode_from_copy(), to decode an encoded #DR_ISA_REGDEPS instruction
* into an #instr_t.
derekbruening marked this conversation as resolved.
Show resolved Hide resolved
*
* A #DR_ISA_REGDEPS #instr_t holds only the encoded information described in the
* encoding scheme, which is:
* - categories (from #dr_instr_category_t), to indicate the type of operation
* performed (e.g., load, store, floating point math operation, branch, etc.);
* - arithmetic flags, with no distinction between different flags, we only report if
* at least one flag was read and/or written;
* - number of source and destination register operands;
* - operation size;
edeiana marked this conversation as resolved.
Show resolved Hide resolved
* - list of register operand identifiers, separated in source and destination;
edeiana marked this conversation as resolved.
Show resolved Hide resolved
* - ISA mode, which is #DR_ISA_REGDEPS.
*
* Querying additional information (e.g., the instruction opcode) will return the
* default value generated by how the instruction was created. If instr_create() was
* used, then zero will be returned. If the #instr_t was allocated on the stack, then
* all values not described above are undefined.
edeiana marked this conversation as resolved.
Show resolved Hide resolved
*/
} dr_isa_mode_t;

DR_API
Expand Down
10 changes: 10 additions & 0 deletions core/ir/encode_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
/* encode_shared.c -- cross-platform encodingn routines */

#include "../globals.h"
#include "isa_regdeps/encode.h"
#include "arch.h"
#include "instr.h"
#include "decode.h"
Expand Down Expand Up @@ -131,6 +132,15 @@ byte *
instr_encode_to_copy(void *drcontext, instr_t *instr, byte *copy_pc, byte *final_pc)
{
dcontext_t *dcontext = (dcontext_t *)drcontext;

/* #DR_ISA_REGDEPS synthetic ISA has its own encoder.
* XXX i#1684: when DR can be built with full dynamic architecture selection we won't
* need to pollute the encoding of other architectures with this synthetic ISA special
* case.
*/
if (instr_get_isa_mode(instr) == DR_ISA_REGDEPS)
return encode_isa_regdeps(dcontext, instr, copy_pc);

return instr_encode_arch(dcontext, instr, copy_pc, final_pc, true,
NULL _IF_DEBUG(true));
}
Expand Down
27 changes: 23 additions & 4 deletions core/ir/instr_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,14 @@ struct _instr_t {

uint opcode;

# ifdef X86
/* PR 251479: offset into instr's raw bytes of rip-relative 4-byte displacement */
byte rip_rel_pos;
# endif
union {
/* PR 251479: offset into instr's raw bytes of rip-relative 4-byte displacement */
edeiana marked this conversation as resolved.
Show resolved Hide resolved
byte rip_rel_pos;
/* PR #6691: size of source data (i.e., read) an instruction operates on.
edeiana marked this conversation as resolved.
Show resolved Hide resolved
* Note that opnd_size_t is an alias for byte.
*/
opnd_size_t operation_size;
edeiana marked this conversation as resolved.
Show resolved Hide resolved
};

/* we dynamically allocate dst and src arrays b/c x86 instrs can have
* up to 8 of each of them, but most have <=2 dsts and <=3 srcs, and we
Expand Down Expand Up @@ -2095,6 +2099,21 @@ DR_API
instr_t *
instr_convert_short_meta_jmp_to_long(void *drcontext, instrlist_t *ilist, instr_t *instr);

DR_API
/**
* Converts a real ISA (e.g., #DR_ISA_AMD64) instruction \p instr_real_isa into a
* #DR_ISA_REGDEPS instruction and stores it into \p instr_regdeps_isa.
* Assumes \p instr_regdeps_isa has been allocated by the caller (e.g., using
* instr_create()).
* Assumes \p instr_real_isa is a fully-decoded or synthesized instruction of a real ISA
* with valid operand information.
* \note \p instr_regdeps_isa will contain only the information of a #DR_ISA_REGDEPS
* synthetic instruction.
*/
void
instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
instr_t *instr_regdeps_isa);

DR_API
/**
* Given \p eflags, returns whether or not the conditional branch, \p
Expand Down
137 changes: 137 additions & 0 deletions core/ir/instr_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#define INSTR_INLINE extern inline

#include "../globals.h"
#include "isa_regdeps/encoding_common.h"
#include "instr.h"
#include "arch.h"
#include "../link.h"
Expand Down Expand Up @@ -2999,6 +3000,142 @@ instr_uses_fp_reg(instr_t *instr)
return false;
}

void
instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
instr_t *instr_regdeps_isa)
{
/* Retrieve number of register destination operands from real ISA instruction.
* Note that a destination operand that is a memory renference should have its
* registers (if any) counted as source operands, since they are being read.
* We use [src|dst]_reg_used to keep track of registers we've seen and avoid
* duplicates.
*/
bool src_reg_used[MAX_NUM_REGS];
memset(src_reg_used, 0, sizeof(src_reg_used));
uint num_srcs = 0;
bool dst_reg_used[MAX_NUM_REGS];
memset(dst_reg_used, 0, sizeof(dst_reg_used));
uint num_dsts = 0;
uint instr_real_num_dsts = (uint)instr_num_dsts(instr_real_isa);
for (uint dst_index = 0; dst_index < instr_real_num_dsts; ++dst_index) {
opnd_t dst_opnd = instr_get_dst(instr_real_isa, dst_index);
uint num_regs_used_by_opnd = (uint)opnd_num_regs_used(dst_opnd);
if (opnd_is_memory_reference(dst_opnd)) {
for (uint opnd_index = 0; opnd_index < num_regs_used_by_opnd; ++opnd_index) {
reg_id_t reg = opnd_get_reg_used(dst_opnd, opnd_index);
/* Map sub-registers to their containing register.
*/
reg_id_t reg_canonical = reg_to_pointer_sized(reg);
if (!src_reg_used[reg_canonical]) {
++num_srcs;
src_reg_used[reg_canonical] = true;
}
}
} else {
for (uint opnd_index = 0; opnd_index < num_regs_used_by_opnd; ++opnd_index) {
reg_id_t reg = opnd_get_reg_used(dst_opnd, opnd_index);
/* Map sub-registers to their containing register.
*/
reg_id_t reg_canonical = reg_to_pointer_sized(reg);
if (!dst_reg_used[reg_canonical]) {
++num_dsts;
dst_reg_used[reg_canonical] = true;
}
}
}
}

/* Retrieve number of register source operands from real ISA instruction.
* We use max_src_opnd_size_bytes to keep track of the size of the largest source
* operand.
* We count the number of bytes instead of using opnd_size_t to avoid relying on
* OPSZ_ enum values.
* We convert max_src_opnd_size_bytes to its corresponding OPSZ_ enum value later on,
derekbruening marked this conversation as resolved.
Show resolved Hide resolved
* and store it into operation_size.
*/
uint max_src_opnd_size_bytes = 0;
uint instr_real_num_srcs = (uint)instr_num_srcs(instr_real_isa);
for (uint i = 0; i < instr_real_num_srcs; ++i) {
opnd_t src_opnd = instr_get_src(instr_real_isa, i);
opnd_size_t opnd_size = opnd_get_size(src_opnd);
uint opnd_size_bytes = opnd_size_in_bytes(opnd_size);
if (opnd_size_bytes > max_src_opnd_size_bytes)
max_src_opnd_size_bytes = opnd_size_bytes;
uint num_regs_used_by_opnd = (uint)opnd_num_regs_used(src_opnd);
for (uint opnd_index = 0; opnd_index < num_regs_used_by_opnd; ++opnd_index) {
reg_id_t reg = opnd_get_reg_used(src_opnd, opnd_index);
/* Map sub-registers to their containing register.
*/
reg_id_t reg_canonical = reg_to_pointer_sized(reg);
if (!src_reg_used[reg_canonical]) {
++num_srcs;
src_reg_used[reg_canonical] = true;
}
}
}

/* Declare num of source and destination operands valid in the converted instruction.
*/
instr_set_num_opnds(drcontext, instr_regdeps_isa, num_dsts, num_srcs);

/* Retrieve arithmetic flags from real ISA instruction.
* If the real ISA instruction reads or writes one or more arithmetic flag, all
* arithmetic flags will be set to read or written in the converted instruction.
* Note that this operation can trigger additional encoding and decoding of
* instr_real_isa, depending on its decoding level.
*/
uint eflags_instr_real = instr_get_arith_flags(instr_real_isa, DR_QUERY_DEFAULT);
uint eflags_instr_regdeps = 0;
if (TESTANY(EFLAGS_WRITE_ARITH, eflags_instr_real))
eflags_instr_regdeps |= EFLAGS_WRITE_ARITH;
if (TESTANY(EFLAGS_READ_ARITH, eflags_instr_real))
eflags_instr_regdeps |= EFLAGS_READ_ARITH;
instr_regdeps_isa->eflags = eflags_instr_regdeps;
instr_set_arith_flags_valid(instr_regdeps_isa, true);

/* Retrieve category of real ISA instruction and set it directly as the category of
* the converted instruction. No changes needed here.
*/
instr_set_category(instr_regdeps_isa, instr_get_category(instr_real_isa));

/* Convert max_src_opnd_size_bytes from number of bytes to opnd_size_t (which holds
* OPSZ_ enum values).
*/
instr_regdeps_isa->operation_size = opnd_size_from_bytes(max_src_opnd_size_bytes);

/* Set the source and destination register operands for the converted instruction.
*/
if (num_dsts > 0) {
uint reg_counter = 0;
for (uint reg = 0; reg < MAX_NUM_REGS; ++reg) {
if (dst_reg_used[reg]) {
opnd_t dst_opnd = opnd_create_reg((reg_id_t)reg);
instr_set_dst(instr_regdeps_isa, reg_counter, dst_opnd);
++reg_counter;
}
}
}

if (num_srcs > 0) {
uint reg_counter = 0;
for (uint reg = 0; reg < MAX_NUM_REGS; ++reg) {
if (src_reg_used[reg]) {
opnd_t src_opnd = opnd_create_reg((reg_id_t)reg);
instr_set_src(instr_regdeps_isa, reg_counter, src_opnd);
++reg_counter;
}
}
}

/* Declare converted instruction operands to be valid.
*/
instr_set_operands_valid(instr_regdeps_isa, true);

/* Set converted instruction ISA mode to be DR_ISA_REGDEPS.
*/
instr_set_isa_mode(instr_regdeps_isa, DR_ISA_REGDEPS);
}

/* We place these here rather than in mangle_shared.c to avoid the work of
* linking mangle_shared.c into drdecodelib.
*/
Expand Down
Loading
Loading