Skip to content

Commit

Permalink
TriCore IL: fix CSUB/CSUBN (#4409)
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow authored Mar 31, 2024
1 parent 9a27c4f commit 8f7f03c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
30 changes: 19 additions & 11 deletions librz/arch/isa/tricore/tricore_il.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,8 @@ static RzILOpPure *VARG_wrap(const char *name) {
#undef VARG
#define VARG(n) VARG_wrap(n)

static RzAnalysisLiftedILOp status_conditional(RzILOpPure *cnd);

static RzAnalysisLiftedILOp ST_MB(RzILOpPure *dst, size_t n, ...) {
rz_return_val_if_fail(dst && n > 0, rz_il_op_new_nop());
va_list args;
Expand Down Expand Up @@ -2006,9 +2008,11 @@ static RzILOpEffect *e_op2_cond(
const char *r, RzILOpPure *a, RzILOpPure *b, RzILOpPure *cond,
RzILOpPure *(*op)(RzILOpPure *x, RzILOpPure *y)) {

RzILOpEffect *e = SEQ2(SETL("result", op(a, b)),
SETG(r, VARL("result")));
return f_overflow32(e);
return SEQ4(
SETL("condition", cond),
SETL("result", ITE(VARL("condition"), op(a, b), DUP(a))),
SETG(r, VARL("result")),
status_conditional(VARL("condition")));
}

static RzILOpEffect *packed_op2_sov(
Expand Down Expand Up @@ -2192,18 +2196,22 @@ static RzAnalysisLiftedILOp lift_add(RzAsmTriCoreContext *ctx) {
return NULL;
}

static RzAnalysisLiftedILOp status_conditional(RzILOpPure *cnd) {
return SEQ6(
SETL("overflow", OR(SGT(VARL("result"), S32(0x7FFFFFFF)), SLT(VARL("result"), S32(-80000000)))),
BRANCH(cnd, set_PSW_V(BOOL_TO_BV32(VARL("overflow"))), NOP()),
BRANCH(AND(DUP(cnd), VARL("overflow")), set_PSW_SV(U32(1)), NOP()),
SETL("advanced_overflow", XOR(NON_ZERO(BITS32(VARL("result"), 30, 1)), NON_ZERO(BITS32(VARL("result"), 31, 1)))),
BRANCH(DUP(cnd), set_PSW_AV(BOOL_TO_BV32(VARL("advanced_overflow"))), NOP()),
BRANCH(AND(DUP(cnd), VARL("advanced_overflow")), set_PSW_SAV(U32(1)), NOP()));
}

static RzAnalysisLiftedILOp e_cadd(const char *dst, RzILOpPure *cnd, RzILOpPure *a, RzILOpPure *b) {
return SEQ9(
return SEQ4(
SETL("condition", cnd),
SETL("result", ITE(VARL("condition"), ADD(a, b), DUP(a))),
SETG(dst, VARL("result")),
/// Status
SETL("overflow", OR(SGT(VARL("result"), S32(0x7FFFFFFF)), SLT(VARL("result"), S32(-80000000)))),
BRANCH(VARL("condition"), set_PSW_V(BOOL_TO_BV32(VARL("overflow"))), NOP()),
BRANCH(AND(VARL("condition"), VARL("overflow")), set_PSW_SV(U32(1)), NOP()),
SETL("advanced_overflow", XOR(NON_ZERO(BITS32(VARL("result"), 30, 1)), NON_ZERO(BITS32(VARL("result"), 31, 1)))),
BRANCH(VARL("condition"), set_PSW_AV(BOOL_TO_BV32(VARL("advanced_overflow"))), NOP()),
BRANCH(AND(VARL("condition"), VARL("advanced_overflow")), set_PSW_SAV(U32(1)), NOP()));
status_conditional(VARL("condition")));
}

static RzAnalysisLiftedILOp lift_cadd(RzAsmTriCoreContext *ctx) {
Expand Down
4 changes: 2 additions & 2 deletions test/db/asm/tricore
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,8 @@ d "subs.u d0, d0, d0" 0b00b000 0x0 (seq (set result (let x (- (var d0) (var d0))
d "subx d0, d0, d0" 0b00c000 0x0 (seq (set result (- (var d0) (var d0))) (set d0 (var result)) (set carry_out (& (>> (+ (+ (var d0) (~- (var d0))) (bv 32 0x1)) (bv 32 0x0) false) (bv 32 0x1))) (set PSW (| (& (var PSW) (bv 32 0x7fffffff)) (<< (& (var carry_out) (bv 32 0x1)) (bv 32 0x1f) false))))
d "sub.b d0, d0, d0" 0b008004 0x0 (seq (set result_byte3 (- (cast 8 false (& (>> (var d0) (bv 32 0x18) false) (bv 32 0xff))) (cast 8 false (& (>> (var d0) (bv 32 0x18) false) (bv 32 0xff))))) (set result_byte2 (- (cast 8 false (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xff))) (cast 8 false (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xff))))) (set result_byte1 (- (cast 8 false (& (>> (var d0) (bv 32 0x8) false) (bv 32 0xff))) (cast 8 false (& (>> (var d0) (bv 32 0x8) false) (bv 32 0xff))))) (set result_byte0 (- (cast 8 false (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xff))) (cast 8 false (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xff))))) (set result (| (cast 32 false (<< (var result_byte3) (bv 32 0x18) false)) (| (cast 32 false (<< (var result_byte2) (bv 32 0x10) false)) (| (cast 32 false (<< (var result_byte1) (bv 32 0x8) false)) (cast 32 false (var result_byte0)))))) (set d0 (var result)) (set ov3 (|| (! (ule (var result_byte3) (bv 8 0x7f))) (&& (sle (var result_byte3) (bv 8 0x80)) (! (== (var result_byte3) (bv 8 0x80)))))) (set ov2 (|| (! (ule (var result_byte2) (bv 8 0x7f))) (&& (sle (var result_byte2) (bv 8 0x80)) (! (== (var result_byte2) (bv 8 0x80)))))) (set ov1 (|| (! (ule (var result_byte1) (bv 8 0x7f))) (&& (sle (var result_byte1) (bv 8 0x80)) (! (== (var result_byte1) (bv 8 0x80)))))) (set ov0 (|| (! (ule (var result_byte0) (bv 8 0x7f))) (&& (sle (var result_byte0) (bv 8 0x80)) (! (== (var result_byte0) (bv 8 0x80)))))) (set overflow (|| (|| (var ov1) (var ov0)) (|| (var ov3) (var ov2)))) (set aov3 (^^ (! (is_zero (& (>> (var result_byte3) (bv 8 0x7) false) (bv 8 0x1)))) (! (is_zero (& (>> (var result_byte3) (bv 8 0x6) false) (bv 8 0x1)))))) (set aov2 (^^ (! (is_zero (& (>> (var result_byte2) (bv 8 0x7) false) (bv 8 0x1)))) (! (is_zero (& (>> (var result_byte2) (bv 8 0x6) false) (bv 8 0x1)))))) (set aov1 (^^ (! (is_zero (& (>> (var result_byte1) (bv 8 0x7) false) (bv 8 0x1)))) (! (is_zero (& (>> (var result_byte1) (bv 8 0x6) false) (bv 8 0x1)))))) (set aov0 (^^ (! (is_zero (& (>> (var result_byte0) (bv 8 0x7) false) (bv 8 0x1)))) (! (is_zero (& (>> (var result_byte0) (bv 8 0x6) false) (bv 8 0x1)))))) (set advanced_overflow (|| (|| (var aov1) (var aov0)) (|| (var aov3) (var aov2)))) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) (branch (var overflow) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (branch (var advanced_overflow) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "sub.h d0, d0, d0" 0b008006 0x0 (seq (set result_hw1 (- (cast 16 false (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xffff))) (cast 16 false (& (>> (var d0) (bv 32 0x10) false) (bv 32 0xffff))))) (set result_hw0 (- (cast 16 false (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xffff))) (cast 16 false (& (>> (var d0) (bv 32 0x0) false) (bv 32 0xffff))))) (set result (| (cast 32 false (<< (var result_hw1) (bv 32 0x10) false)) (cast 32 false (var result_hw0)))) (set d0 (var result)) (set ov1 (|| (! (ule (var result_hw1) (bv 16 0x7fff))) (&& (sle (var result_hw1) (bv 16 0x8000)) (! (== (var result_hw1) (bv 16 0x8000)))))) (set ov0 (|| (! (ule (var result_hw0) (bv 16 0x7fff))) (&& (sle (var result_hw0) (bv 16 0x8000)) (! (== (var result_hw0) (bv 16 0x8000)))))) (set overflow (|| (var ov1) (var ov0))) (set aov1 (^^ (! (is_zero (& (>> (var result_hw1) (bv 16 0xf) false) (bv 16 0x1)))) (! (is_zero (& (>> (var result_hw1) (bv 16 0xe) false) (bv 16 0x1)))))) (set aov0 (^^ (! (is_zero (& (>> (var result_hw0) (bv 16 0xf) false) (bv 16 0x1)))) (! (is_zero (& (>> (var result_hw0) (bv 16 0xe) false) (bv 16 0x1)))))) (set advanced_overflow (|| (var aov1) (var aov0))) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) (branch (var overflow) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (branch (var advanced_overflow) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "csub d0, d0, d0, d0" 2b002000 0x0 (seq (set result (- (var d0) (var d0))) (set d0 (var result)) (set overflow (|| (! (ule (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0x80000000)) (! (== (var result) (bv 32 0x80000000)))))) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))))) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) (branch (var overflow) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (branch (var advanced_overflow) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "csubn d0, d0, d0, d0" 2b003000 0x0 (seq (set result (- (var d0) (var d0))) (set d0 (var result)) (set overflow (|| (! (ule (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0x80000000)) (! (== (var result) (bv 32 0x80000000)))))) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))))) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) (branch (var overflow) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (branch (var advanced_overflow) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "csub d0, d0, d0, d0" 2b002000 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 "csubn d0, d0, d0, d0" 2b003000 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 "mul d0, d0" e200 0x0 (seq (set result (* (var d0) (var d0))) (set d0 (var result)) (set overflow (|| (! (ule (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0x80000000)) (! (== (var result) (bv 32 0x80000000)))))) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))))) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) (branch (var overflow) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (branch (var advanced_overflow) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "mul d0, d0, #0" 53002000 0x0 (seq (set result (* (var d0) (bv 32 0x0))) (set d0 (var result)) (set overflow (|| (! (ule (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0x80000000)) (! (== (var result) (bv 32 0x80000000)))))) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))))) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) (branch (var overflow) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (branch (var advanced_overflow) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
d "mul d0, d0, d0" 73000a00 0x0 (seq (set result (* (var d0) (var d0))) (set d0 (var result)) (set overflow (|| (! (ule (var result) (bv 32 0x7fffffff))) (&& (sle (var result) (bv 32 0x80000000)) (! (== (var result) (bv 32 0x80000000)))))) (set advanced_overflow (^^ (! (is_zero (& (>> (var result) (bv 32 0x1f) false) (bv 32 0x1)))) (! (is_zero (& (>> (var result) (bv 32 0x1e) false) (bv 32 0x1)))))) (set PSW (| (& (var PSW) (bv 32 0xbfffffff)) (<< (& (ite (var overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1e) false))) (set PSW (| (& (var PSW) (bv 32 0xefffffff)) (<< (& (ite (var advanced_overflow) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1)) (bv 32 0x1c) false))) (branch (var overflow) (set PSW (| (& (var PSW) (bv 32 0xdfffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1d) false))) nop) (branch (var advanced_overflow) (set PSW (| (& (var PSW) (bv 32 0xf7ffffff)) (<< (& (bv 32 0x1) (bv 32 0x1)) (bv 32 0x1b) false))) nop))
Expand Down

0 comments on commit 8f7f03c

Please sign in to comment.