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

TriCore IL: fix CSUB/CSUBN #4409

Merged
merged 2 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading