Skip to content

Commit

Permalink
Add lt.**
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow committed Dec 22, 2023
1 parent faccf2c commit d509634
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 13 deletions.
78 changes: 65 additions & 13 deletions librz/analysis/arch/tricore/tricore_il.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,18 @@ static RzILOpPure *carry(RzILOpPure *a, RzILOpPure *b, RzILOpPure *c) {
RzILOpPure *val = ADD(ADD(a, b), c);
return BITS32(val, 0, 1);
}
static RzILOpEffect *packed_binary_op(
#define ONES(l) U32((1ULL << l) - 1ULL)
static RzILOpPure *f_op2_lt(
RzILOpPure *a, RzILOpPure *b, unsigned i, unsigned l,
RzILOpPure *(op)(RzILOpPure *, RzILOpPure *)) {
if (i || (l && l != 32)) {
a = BITS32(a, i, l);
b = BITS32(b, i, l);
}
return LET("a_tmp", a,
LET("b_tmp", b, ITE(op(VARLP("a_tmp"), VARLP("b_tmp")), ONES(l), U32(0))));
}
static RzILOpEffect *packed_op2(
const char *r, RzILOpPure *a, RzILOpPure *b, unsigned n,
RzILOpPure *(*op)(RzILOpPure *a, RzILOpPure *b, unsigned n, unsigned l, RzILOpPure *(*f)(RzILOpPure *x, RzILOpPure *y)),
RzILOpPure *(*f)(RzILOpPure *x, RzILOpPure *y)) {
Expand All @@ -1149,6 +1160,26 @@ static RzILOpEffect *packed_binary_op(
return SETG(r, val);
}

static RzILOpEffect *packed_op2_(
const char *r, RzILOpPure *a, RzILOpPure *b, unsigned n,
RzILOpPure *(*op)(RzILOpPure *x, RzILOpPure *y)) {
RzILOpPure *val = NULL;
if (n == Word) {
val = f_op2_lt(a, b, 0, 0, op);
} else if (n == HalfWord) {
RzILOpPure *h1 = f_op2_lt(a, b, 16, 16, op);
RzILOpPure *h0 = f_op2_lt(DUP(a), DUP(b), 0, 16, op);
val = packed_2halfword(h1, h0);
} else if (n == Byte) {
RzILOpPure *b3 = f_op2_lt(a, b, 24, 8, op);
RzILOpPure *b2 = f_op2_lt(DUP(a), DUP(b), 16, 8, op);
RzILOpPure *b1 = f_op2_lt(DUP(a), DUP(b), 8, 8, op);
RzILOpPure *b0 = f_op2_lt(DUP(a), DUP(b), 0, 8, op);
val = packed_4byte(b3, b2, b1, b0);
}
return SETG(r, val);
}

static RzILOpEffect *packed_op3(
const char *r, RzILOpPure *a, RzILOpPure *b, RzILOpPure *c, unsigned n,
RzILOpPure *(*op)(RzILOpPure *a, RzILOpPure *b, RzILOpPure *c, unsigned n, unsigned l, RzILOpPure *(*f)(RzILOpPure *x, RzILOpPure *y)),
Expand Down Expand Up @@ -1261,15 +1292,15 @@ static RzAnalysisLiftedILOp lift_add(RzAsmTriCoreContext *ctx) {
case 0x0b: {
switch (extract32(ctx->word, 20, 8)) {
case 0x00: return SETG(R(0), ADD(VARG(R(1)), VARG(R(2))));
case 0x40: return packed_binary_op(R(0), VARG(R(1)), VARG(R(2)), Byte, f_ADD, NULL);
case 0x60: return packed_binary_op(R(0), VARG(R(1)), VARG(R(2)), HalfWord, f_ADD, NULL);
case 0x40: return packed_op2(R(0), VARG(R(1)), VARG(R(2)), Byte, f_ADD, NULL);
case 0x60: return packed_op2(R(0), VARG(R(1)), VARG(R(2)), HalfWord, f_ADD, NULL);
case 0x05: return SEQ2(
packed_op3(R(0), VARG(R(1)), VARG(R(2)), PSW_C(), Word, f_ADDC, NULL),
set_PSW_C(carry(VARG(R(1)), VARG(R(2)), PSW_C())));
case /*ADDS RR*/ 0x02: return SETG(R(0), ssov(ADD(VARG(R(1)), VARG(R(2))), U32(32)));
case /*ADDS.U RR*/ 0x03: return SETG(R(0), suov(ADD(VARG(R(1)), VARG(R(2))), U32(32)));
case /*ADDS.H RR*/ 0x62: return packed_binary_op(R(0), VARG(R(1)), VARG(R(2)), HalfWord, f_ADD, ssov);
case /*ADDS.HU RR*/ 0x63: return packed_binary_op(R(0), VARG(R(1)), VARG(R(2)), HalfWord, f_ADDU, suov);
case /*ADDS.H RR*/ 0x62: return packed_op2(R(0), VARG(R(1)), VARG(R(2)), HalfWord, f_ADD, ssov);
case /*ADDS.HU RR*/ 0x63: return packed_op2(R(0), VARG(R(1)), VARG(R(2)), HalfWord, f_ADDU, suov);
case /*ADDX RR*/ 0x04: return SEQ2(
packed_op3(R(0), VARG(R(1)), VARG(R(2)), S32(0), Word, f_ADDC, NULL),
set_PSW_C(carry(VARG(R(1)), VARG(R(2)), S32(0))));
Expand Down Expand Up @@ -1622,14 +1653,35 @@ static RzAnalysisLiftedILOp tricore_il_op(RzAsmTriCoreContext *ctx, RzAnalysis *
}
break;
}
case TRICORE_INS_LT_B:
case TRICORE_INS_LT_BU:
case TRICORE_INS_LT_H:
case TRICORE_INS_LT_HU:
case TRICORE_INS_LT_U:
case TRICORE_INS_LT_W:
case TRICORE_INS_LT_WU:
case TRICORE_INS_LT: break;
case TRICORE_INS_LT_B: return packed_op2_(R(0), VARG(R(1)), VARG(R(2)), Byte, rz_il_op_new_slt);
case TRICORE_INS_LT_BU: return packed_op2_(R(0), VARG(R(1)), VARG(R(2)), Byte, rz_il_op_new_ult);
case TRICORE_INS_LT_H: return packed_op2_(R(0), VARG(R(1)), VARG(R(2)), HalfWord, rz_il_op_new_slt);
case TRICORE_INS_LT_HU: return packed_op2_(R(0), VARG(R(1)), VARG(R(2)), HalfWord, rz_il_op_new_ult);
case TRICORE_INS_LT_W: return SETG(R(0), f_op2_lt(VARG(R(1)), VARG(R(2)), 0, Word, rz_il_op_new_slt));
case TRICORE_INS_LT_WU: return SETG(R(0), f_op2_lt(VARG(R(1)), VARG(R(2)), 0, Word, rz_il_op_new_ult));
case TRICORE_INS_LT:
case TRICORE_INS_LT_U: {
switch (InsnB0) {
case 0x8b:
switch (extract32(ctx->word, 21, 7)) {
case /*LT(RC)*/ 0x12: return SETG(R(0), BOOL_TO_BV32(SLT(VARG(R(1)), sign_ext32_bv(I(2), 9))));
case /*LT.U(RC)*/ 0x13: return SETG(R(0), BOOL_TO_BV32(ULT(VARG(R(1)), U32(I(2)))));
default: break;
}
break;
case 0x0b:
switch (extract32(ctx->word, 20, 8)) {
case /*LT(RR)*/ 0x12: return SETG(R(0), BOOL_TO_BV32(SLT(VARG(R(1)), VARG(R(2)))));
case /*LT.U(RC)*/ 0x13: return SETG(R(0), BOOL_TO_BV32(ULT(VARG(R(1)), VARG(R(2)))));
default: break;
}
break;
case /*LT(SRC)*/ 0xfa: return SETG("d15", BOOL_TO_BV32(SLT(VARG(R(0)), sign_ext32_bv(I(1), 4))));
case /*LT(SRR)*/ 0x7a: return SETG("d15", BOOL_TO_BV32(SLT(VARG(R(0)), VARG(R(1)))));
default: break;
}
break;
}
case TRICORE_INS_GE_U:
case TRICORE_INS_GE:
case TRICORE_INS_EQANY_B:
Expand Down
13 changes: 13 additions & 0 deletions test/db/asm/tricore
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,16 @@ d "cadd d0, d0, d0, #0" ab000000 0x0 (seq (set condition (! (is_zero (var d0))))
d "caddn d0, d15, #0" ca00 0x0 (seq (set condition (is_zero (var d15))) (set result (ite (var condition) (+ (var d0) (bv 32 0x0)) (var d0))) (set d0 (var result)) (set overflow (|| (! (sle (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0xfb3b4c00)) (! (== (var result) (bv 32 0xfb3b4c00)))))) (branch (var condition) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) nop) (branch (&& (var condition) (var overflow)) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))))) (branch (var condition) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) nop) (branch (&& (var condition) (var advanced_overflow)) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "caddn d0, d0, d0, d0" 2b001000 0x0 (seq (set condition (! (is_zero (var d0)))) (set result (ite (var condition) (+ (var d0) (var d0)) (var d0))) (set d0 (var result)) (set overflow (|| (! (sle (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0xfb3b4c00)) (! (== (var result) (bv 32 0xfb3b4c00)))))) (branch (var condition) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) nop) (branch (&& (var condition) (var overflow)) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))))) (branch (var condition) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) nop) (branch (&& (var condition) (var advanced_overflow)) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "caddn d0, d0, d0, #0" ab002000 0x0 (seq (set condition (is_zero (var d0))) (set result (ite (var condition) (+ (var d0) (bv 32 0x0)) (var d0))) (set d0 (var result)) (set overflow (|| (! (sle (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0xfb3b4c00)) (! (== (var result) (bv 32 0xfb3b4c00)))))) (branch (var condition) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) nop) (branch (&& (var condition) (var overflow)) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))))) (branch (var condition) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) nop) (branch (&& (var condition) (var advanced_overflow)) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "lt d15, d0, d0" 7a00 0x0 (set d15 (ite (&& (sle (var d0) (var d0)) (! (== (var d0) (var d0)))) (bv 32 0x1) (bv 32 0x0)))
d "lt d15, d0, #0" fa00 0x0 (set d15 (ite (&& (sle (var d0) (bv 32 0x0)) (! (== (var d0) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)))
d "lt d0, d0, d0" 0b002001 0x0 (set d0 (ite (&& (sle (var d0) (var d0)) (! (== (var d0) (var d0)))) (bv 32 0x1) (bv 32 0x0)))
d "lt d0, d0, #0" 8b004002 0x0 (set d0 (ite (&& (sle (var d0) (bv 32 0x0)) (! (== (var d0) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)))
d "lt.a d0, a0, a0" 01002004 0x0 (set d0 (ite (&& (ule (var a0) (var a0)) (! (== (var a0) (var a0)))) (bv 32 0x1) (bv 32 0x0)))
d "lt.b d0, d0, d0" 0b002005 0x0 (set d0 (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x18) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x18) false) (bv 32 0xff)) (ite (&& (sle (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))) (bv 32 0x18) false)) (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xff)) (ite (&& (sle (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))) (bv 32 0x10) false)) (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x8) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x8) false) (bv 32 0xff)) (ite (&& (sle (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))) (bv 32 0x8) false)) (cast 32 false (let a_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xff)) (ite (&& (sle (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))))))))
d "lt.bu d0, d0, d0" 0b003005 0x0 (set d0 (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x18) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x18) false) (bv 32 0xff)) (ite (&& (ule (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))) (bv 32 0x18) false)) (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xff)) (ite (&& (ule (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))) (bv 32 0x10) false)) (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x8) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x8) false) (bv 32 0xff)) (ite (&& (ule (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))) (bv 32 0x8) false)) (cast 32 false (let a_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xff)) (let b_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xff)) (ite (&& (ule (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xff) (bv 32 0x0)))))))))
d "lt.h d0, d0, d0" 0b002007 0x0 (set d0 (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xffff)) (let b_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xffff)) (ite (&& (sle (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xffff) (bv 32 0x0)))) (bv 32 0x10) false)) (cast 32 false (let a_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xffff)) (let b_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xffff)) (ite (&& (sle (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xffff) (bv 32 0x0)))))))
d "lt.hu d0, d0, d0" 0b003007 0x0 (set d0 (| (cast 32 false (<< (let a_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xffff)) (let b_tmp (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xffff)) (ite (&& (ule (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xffff) (bv 32 0x0)))) (bv 32 0x10) false)) (cast 32 false (let a_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xffff)) (let b_tmp (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xffff)) (ite (&& (ule (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xffff) (bv 32 0x0)))))))
d "lt.u d0, d0, d0" 0b003001 0x0 (set d0 (ite (&& (ule (var d0) (var d0)) (! (== (var d0) (var d0)))) (bv 32 0x1) (bv 32 0x0)))
d "lt.u d0, d0, #0" 8b006002 0x0 (set d0 (ite (&& (ule (var d0) (bv 32 0x0)) (! (== (var d0) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)))
d "lt.w d0, d0, d0" 0b002009 0x0 (set d0 (let a_tmp (var d0) (let b_tmp (var d0) (ite (&& (sle (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xffffffff) (bv 32 0x0)))))
d "lt.wu d0, d0, d0" 0b003009 0x0 (set d0 (let a_tmp (var d0) (let b_tmp (var d0) (ite (&& (ule (var a_tmp) (var b_tmp)) (! (== (var a_tmp) (var b_tmp)))) (bv 32 0xffffffff) (bv 32 0x0)))))

0 comments on commit d509634

Please sign in to comment.