Skip to content

Commit

Permalink
Handle read/write of alias P3:0 register
Browse files Browse the repository at this point in the history
  • Loading branch information
Rot127 committed Nov 12, 2023
1 parent 33a05ca commit 7abaaad
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 6 deletions.
41 changes: 36 additions & 5 deletions handwritten/hexagon_il_c/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,13 @@ static void log_reg_write(RZ_BORROW HexInsnPktBundle *bundle, ut8 reg_num, HexRe
pkt->il_op_stats.gpr_written |= (1 << reg_num);
break;
case HEX_REG_CLASS_CTR_REGS64:
if (hex_ctr_immut_masks[reg_num + 1] != HEX_IMMUTABLE_MASK) {
if (hex_ctr_immut_masks[reg_num + 1] != HEX_IMMUTABLE_REG) {
pkt->il_op_stats.ctr_written |= (1 << (reg_num + 1));
}
// fallthrough
case HEX_REG_CLASS_MOD_REGS:
case HEX_REG_CLASS_CTR_REGS:
if (hex_ctr_immut_masks[reg_num] != HEX_IMMUTABLE_MASK) {
if (hex_ctr_immut_masks[reg_num] != HEX_IMMUTABLE_REG) {
pkt->il_op_stats.ctr_written |= (1 << reg_num);
}
break;
Expand Down Expand Up @@ -537,6 +537,7 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_write_reg(RZ_BORROW HexInsnPktBundle *bundle, co
const char *low_name = NULL;
RzILOpPure *high_val = NULL;
RzILOpPure *low_val = NULL;
RzILOpEffect *p3_0_write_seq = NULL; // If C4 (P3:0) is written this is non-NULL.
ut32 reg_num = hex_resolve_reg_enum_id(op->class, op->op.reg);
ut32 dest_width = HEX_GPR_WIDTH;
switch (op->class) {
Expand All @@ -556,7 +557,7 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_write_reg(RZ_BORROW HexInsnPktBundle *bundle, co
low_val = CAST(HEX_GPR_WIDTH, IL_FALSE, val);
break;
case HEX_REG_CLASS_CTR_REGS64:
if (hex_ctr_immut_masks[reg_num + 1] != HEX_IMMUTABLE_MASK) {
if (hex_ctr_immut_masks[reg_num + 1] != HEX_IMMUTABLE_REG) {
high_name = hex_get_reg_in_class(HEX_REG_CLASS_CTR_REGS, reg_num + 1, false, true, true);
high_val = SHIFTR0(DUP(val), U8(HEX_GPR_WIDTH));
if (hex_ctr_immut_masks[reg_num + 1] != 0) {
Expand All @@ -566,12 +567,25 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_write_reg(RZ_BORROW HexInsnPktBundle *bundle, co
// fallthrough
case HEX_REG_CLASS_MOD_REGS:
case HEX_REG_CLASS_CTR_REGS:
if (hex_ctr_immut_masks[reg_num] != HEX_IMMUTABLE_MASK) {
if (hex_ctr_immut_masks[reg_num] != HEX_IMMUTABLE_REG) {
low_name = hex_get_reg_in_class(HEX_REG_CLASS_CTR_REGS, reg_num, false, true, true);
low_val = CAST(HEX_GPR_WIDTH, IL_FALSE, val);
if (hex_ctr_immut_masks[reg_num] != 0) {
low_val = get_masked_reg_val(VARG(low_name), low_val, hex_ctr_immut_masks[reg_num]);
}
if (reg_num == 4) {
HexOp pred_op = { 0 };
pred_op.class = HEX_REG_CLASS_PRED_REGS;
pred_op.op.reg = 0;
p3_0_write_seq = hex_write_reg(bundle, &pred_op, CAST(8, IL_FALSE, DUP(low_val)));
pred_op.op.reg = 1;
p3_0_write_seq = SEQ2(hex_write_reg(bundle, &pred_op, CAST(8, IL_FALSE, SHIFTR0(DUP(low_val), U8(8)))), p3_0_write_seq);
pred_op.op.reg = 2;
p3_0_write_seq = SEQ2(hex_write_reg(bundle, &pred_op, CAST(8, IL_FALSE, SHIFTR0(DUP(low_val), U8(16)))), p3_0_write_seq);
pred_op.op.reg = 3;
p3_0_write_seq = SEQ2(hex_write_reg(bundle, &pred_op, CAST(8, IL_FALSE, SHIFTR0(DUP(low_val), U8(24)))), p3_0_write_seq);
break;
}
}
break;
case HEX_REG_CLASS_PRED_REGS:
Expand All @@ -587,6 +601,9 @@ RZ_IPI RZ_OWN RzILOpEffect *hex_write_reg(RZ_BORROW HexInsnPktBundle *bundle, co
}
RzILOpEffect *write_high = high_val ? SETG(high_name, CAST(dest_width, IL_FALSE, high_val)) : NULL;
RzILOpEffect *write_low = low_val ? SETG(low_name, CAST(dest_width, IL_FALSE, low_val)) : NULL;
if (p3_0_write_seq) {
write_low = SEQ2(write_low, p3_0_write_seq);
}
log_reg_write(bundle, reg_num, op->class, false, true);

if (write_high && write_low) {
Expand All @@ -606,7 +623,7 @@ static inline bool read_cond_faulty(RzILOpPure *low_val, RzILOpPure *high_val, u
if (val_width == HEX_GPR64_WIDTH && !high_val) {
return true;
}
return false;
return false;
}

/**
Expand Down Expand Up @@ -674,6 +691,20 @@ RZ_IPI RZ_OWN RzILOpPure *hex_read_reg(RZ_BORROW HexPkt *pkt, const HexOp *op, b
// If read and writes overlap, return the new register for each read.
tmp_reg = true;
}
if (reg_num == 4) {
// C4 alias P3:0 register is the concatenation of all predicate registers.
HexOp pred_op = { 0 };
pred_op.class = HEX_REG_CLASS_PRED_REGS;
pred_op.op.reg = 0;
low_val = hex_read_reg(pkt, &pred_op, tmp_reg);
pred_op.op.reg = 1;
low_val = APPEND(hex_read_reg(pkt, &pred_op, tmp_reg), low_val);
pred_op.op.reg = 2;
low_val = APPEND(hex_read_reg(pkt, &pred_op, tmp_reg), low_val);
pred_op.op.reg = 3;
low_val = APPEND(hex_read_reg(pkt, &pred_op, tmp_reg), low_val);
break;
}
low_name = hex_get_reg_in_class(HEX_REG_CLASS_CTR_REGS, reg_num, false, tmp_reg, true);
if (reg_num == 9) {
low_val = U32(pkt->pkt_addr);
Expand Down
11 changes: 11 additions & 0 deletions handwritten/hexagon_il_h/declarations.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
// SPDX-FileCopyrightText: 2022 Rot127 <[email protected]>
// SPDX-License-Identifier: LGPL-3.0-only

/// Immutable bits of CTR registers as in QEMU.
static const ut64 hex_ctr_immut_masks[32] = {
[HEX_REG_CTR_REGS_C8] = 0xc13000c0, // USR
[HEX_REG_CTR_REGS_C9] = HEX_IMMUTABLE_REG, // PC
[HEX_REG_CTR_REGS_C11] = 0x3f, // GP
[HEX_REG_CTR_REGS_C14] = HEX_IMMUTABLE_REG, // UPCYCLELO
[HEX_REG_CTR_REGS_C15] = HEX_IMMUTABLE_REG, // UPCYCLEHI
[HEX_REG_CTR_REGS_C30] = HEX_IMMUTABLE_REG, // UTIMERLO
[HEX_REG_CTR_REGS_C31] = HEX_IMMUTABLE_REG, // UTIMERHI
};

RZ_IPI bool hex_shuffle_insns(RZ_INOUT HexPkt *p);
RZ_IPI RzILOpEffect *hex_get_il_op(const ut32 addr, const bool get_pkt_op);
RZ_IPI RZ_OWN RzILOpPure *hex_get_rf_property_val(const HexRegFieldProperty property, const HexRegField field);
Expand Down
5 changes: 4 additions & 1 deletion handwritten/hexagon_il_h/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@
#define INC(val, size) ADD(val, UN(size, 1))
#define DEC(val, size) SUB(val, UN(size, 1))
#define HEX_STORE_SLOT_CANCELLED(pkt, slot) hex_cancel_slot(pkt, slot)
#define HEX_FCIRC_ADD(bundle, RxV, offset, mu, CS) hex_fcircadd(bundle, RxV, offset, mu, CS)
#define HEX_FCIRC_ADD(bundle, RxV, offset, mu, CS) hex_fcircadd(bundle, RxV, offset, mu, CS)

#define HEX_IMMUTABLE_REG (~0)
#define HEX_NOT_MASKED 0

0 comments on commit 7abaaad

Please sign in to comment.