Skip to content

Commit

Permalink
Add remaining binops
Browse files Browse the repository at this point in the history
  • Loading branch information
thestr4ng3r committed Aug 30, 2023
1 parent 2c05b41 commit a5954de
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 48 deletions.
49 changes: 46 additions & 3 deletions librz/analysis/arch/gb/gb_il.inc
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,44 @@ static RzILOpEffect *gb_il_and(gb_reg dst_reg, RzILOpBitVector *src) {
SETG("C", IL_FALSE));
}

static RzILOpEffect *gb_il_xor(gb_reg dst_reg, RzILOpBitVector *src) {
RzILOpBitVector *dst = gb_il_read_reg(dst_reg);
return SEQ5(
gb_il_write_reg(dst_reg, LOGXOR(dst, src)),
SETG("Z", IS_ZERO(DUP(dst))),
SETG("N", IL_FALSE),
SETG("H", IL_FALSE),
SETG("C", IL_FALSE));
}

static RzILOpEffect *gb_il_or(gb_reg dst_reg, RzILOpBitVector *src) {
RzILOpBitVector *dst = gb_il_read_reg(dst_reg);
return SEQ5(
gb_il_write_reg(dst_reg, LOGOR(dst, src)),
SETG("Z", IS_ZERO(DUP(dst))),
SETG("N", IL_FALSE),
SETG("H", IL_FALSE),
SETG("C", IL_FALSE));
}

static RzILOpEffect *gb_il_cmp(gb_reg dst_reg, RzILOpBitVector *src) {
RzILOpBitVector *dst = gb_il_read_reg(dst_reg);
return SEQ4(
SETG("Z", EQ(dst, src)),
SETG("N", IL_TRUE),
SETG("H", ULT(UNSIGNED(4, DUP(dst)), UNSIGNED(4, DUP(src)))),
SETG("C", ULT(DUP(dst), DUP(src))));
}

typedef enum {
GB_IL_BINOP_ADD,
GB_IL_BINOP_ADC,
GB_IL_BINOP_SUB,
GB_IL_BINOP_SBC,
GB_IL_BINOP_AND,
GB_IL_BINOP_XOR,
GB_IL_BINOP_OR
GB_IL_BINOP_OR,
GB_IL_BINOP_CMP
} gb_il_binop;

static RzILOpEffect *gb_il_binop_dispatch(gb_il_binop op, gb_reg dst_reg, RzILOpBitVector *src) {
Expand All @@ -310,9 +340,11 @@ static RzILOpEffect *gb_il_binop_dispatch(gb_il_binop op, gb_reg dst_reg, RzILOp
case GB_IL_BINOP_AND:
return gb_il_and(dst_reg, src);
case GB_IL_BINOP_XOR:
return gb_il_xor(dst_reg, src);
case GB_IL_BINOP_OR:
// TODO
return NULL;
return gb_il_or(dst_reg, src);
case GB_IL_BINOP_CMP:
return gb_il_cmp(dst_reg, src);
}
}

Expand Down Expand Up @@ -378,6 +410,17 @@ static RzILOpEffect *gb_il_rot(gb_reg reg, bool right, bool set_z, ut64 op_addr)
SETG("H", IL_FALSE));
}

static RzILOpEffect *gb_il_cpl() {
return SEQ3(
SETG("a", LOGNOT(VARG("a"))),
SETG("N", IL_TRUE),
SETG("H", IL_TRUE));
}

static RzILOpEffect *gb_il_ccf() {
return SETG("C", INV(VARG("C")));
}

// --

static RzILOpEffect *gb_il_cjmp(ut64 dst, gb_flag cond_flag, bool neg) {
Expand Down
85 changes: 69 additions & 16 deletions librz/analysis/p/analysis_gb.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,20 +332,30 @@ static inline void gb_analysis_mov_scf(RzReg *reg, RzAnalysisOp *op) {
rz_strbuf_set(&op->esil, "1,C,:=");
}

static inline void gb_analysis_xor_cpl(RzReg *reg, RzAnalysisOp *op) {
static inline void gb_analysis_xor_cpl(RzAnalysisOpMask mask, RzReg *reg, RzAnalysisOp *op) {
op->dst = rz_analysis_value_new();
op->src[0] = rz_analysis_value_new();
op->dst->reg = rz_reg_get(reg, gb_reg_name(GB_REG_A), RZ_REG_TYPE_GPR);
op->src[0]->imm = 0xff;
rz_strbuf_set(&op->esil, "0xff,a,^=,1,N,:=,1,H,:=");
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_set(&op->esil, "0xff,a,^=,1,N,:=,1,H,:=");
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_cpl();
}
}

static inline void gb_analysis_xor_ccf(RzReg *reg, RzAnalysisOp *op) {
static inline void gb_analysis_xor_ccf(RzAnalysisOpMask mask, RzReg *reg, RzAnalysisOp *op) {
op->dst = rz_analysis_value_new();
op->src[0] = rz_analysis_value_new();
op->dst->reg = rz_reg_get(reg, regs_1[3], RZ_REG_TYPE_GPR);
op->src[0]->imm = 1;
rz_strbuf_set(&op->esil, "C,!=");
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_set(&op->esil, "C,!=");
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_ccf();
}
}

static inline void gb_analysis_cond(RzReg *reg, RzAnalysisOp *op, const ut8 data) {
Expand Down Expand Up @@ -439,16 +449,36 @@ static void gb_analysis_xoaasc(RzAnalysisOpMask mask, RzReg *reg, RzAnalysisOp *
switch (op->type) {
case RZ_ANALYSIS_OP_TYPE_XOR:
if (op->src[0]->memref) {
rz_strbuf_setf(&op->esil, "%s,[1],a,^=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "%s,[1],a,^=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_reg_memref(GB_IL_BINOP_XOR, GB_REG_A, src_regid, op->addr);
}
} else {
rz_strbuf_setf(&op->esil, "%s,a,^=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "%s,a,^=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_reg(GB_IL_BINOP_XOR, GB_REG_A, src_regid);
}
}
break;
case RZ_ANALYSIS_OP_TYPE_OR:
if (op->src[0]->memref) {
rz_strbuf_setf(&op->esil, "%s,[1],a,|=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "%s,[1],a,|=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_reg_memref(GB_IL_BINOP_OR, GB_REG_A, src_regid, op->addr);
}
} else {
rz_strbuf_setf(&op->esil, "%s,a,|=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "%s,a,|=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", reg_name);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_reg(GB_IL_BINOP_OR, GB_REG_A, src_regid);
}
}
break;
case RZ_ANALYSIS_OP_TYPE_AND:
Expand Down Expand Up @@ -532,12 +562,20 @@ static void gb_analysis_xoaasc(RzAnalysisOpMask mask, RzReg *reg, RzAnalysisOp *
}
break;
case RZ_ANALYSIS_OP_TYPE_CMP:
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
if (op->src[0]->memref) {
if (op->src[0]->memref) {
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "%s,[1],a,==,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", reg_name);
} else {
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_reg_memref(GB_IL_BINOP_CMP, GB_REG_A, src_regid, op->addr);
}
} else {
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "%s,a,==,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", reg_name);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_reg(GB_IL_BINOP_CMP, GB_REG_A, src_regid);
}
}
break;
default:
Expand All @@ -555,10 +593,20 @@ static void gb_analysis_xoaasc_imm(RzAnalysisOpMask mask, RzReg *reg, RzAnalysis
op->src[0]->imm = data[1];
switch (op->type) {
case RZ_ANALYSIS_OP_TYPE_XOR:
rz_strbuf_setf(&op->esil, "0x%02x,a,^=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", data[1]);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "0x%02x,a,^=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", data[1]);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_imm(GB_IL_BINOP_XOR, GB_REG_A, data[1]);
}
break;
case RZ_ANALYSIS_OP_TYPE_OR:
rz_strbuf_setf(&op->esil, "0x%02x,a,|=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", data[1]);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "0x%02x,a,|=,$z,Z,:=,0,N,:=,0,H,:=,0,C,:=", data[1]);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_imm(GB_IL_BINOP_OR, GB_REG_A, data[1]);
}
break;
case RZ_ANALYSIS_OP_TYPE_AND:
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
Expand Down Expand Up @@ -606,7 +654,12 @@ static void gb_analysis_xoaasc_imm(RzAnalysisOpMask mask, RzReg *reg, RzAnalysis
}
break;
case RZ_ANALYSIS_OP_TYPE_CMP:
rz_strbuf_setf(&op->esil, "%d,a,==,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", data[1]);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
rz_strbuf_setf(&op->esil, "%d,a,==,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", data[1]);
}
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
op->il_op = gb_il_binop_imm(GB_IL_BINOP_CMP, GB_REG_A, data[1]);
}
break;
}
}
Expand Down Expand Up @@ -1296,12 +1349,12 @@ static int gb_anop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
gb_analysis_cb_rr(mask, analysis->reg, op, 7, false);
break;
case 0x2f:
gb_analysis_xor_cpl(analysis->reg, op); // cpl
gb_analysis_xor_cpl(mask, analysis->reg, op); // cpl
op->cycles = 4;
op->type = RZ_ANALYSIS_OP_TYPE_XOR;
break;
case 0x3f: // ccf
gb_analysis_xor_ccf(analysis->reg, op);
gb_analysis_xor_ccf(mask, analysis->reg, op);
op->cycles = 4;
op->type = RZ_ANALYSIS_OP_TYPE_XOR;
break;
Expand Down
58 changes: 29 additions & 29 deletions test/db/asm/gb
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,17 @@ d "call C, 0x0000" dc0000
d "call Z, 0x0000" cc0000
d "call nC, 0x0000" d40000
d "call nZ, 0x0000" c40000
d "ccf" 3f
d "cp 0x00" fe00
d "cp [hl]" be
d "cp a" bf
d "cp b" b8
d "cp c" b9
d "cp d" ba
d "cp e" bb
d "cp h" bc
d "cp l" bd
d "cpl" 2f
d "ccf" 3f 0x0 (set C (! (var C)))
d "cp 0x42" fe42 0x0 (seq (set Z (== (var a) (bv 8 0x42))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (bv 8 0x42))) (! (== (cast 4 false (var a)) (cast 4 false (bv 8 0x42)))))) (set C (&& (ule (var a) (bv 8 0x42)) (! (== (var a) (bv 8 0x42))))))
d "cp [hl]" be 0x0 (seq (set src (load 0 (append (var h) (var l)))) (set Z (== (var a) (var src))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var src))) (! (== (cast 4 false (var a)) (cast 4 false (var src)))))) (set C (&& (ule (var a) (var src)) (! (== (var a) (var src))))))
d "cp a" bf 0x0 (seq (set Z (== (var a) (var a))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var a))) (! (== (cast 4 false (var a)) (cast 4 false (var a)))))) (set C (&& (ule (var a) (var a)) (! (== (var a) (var a))))))
d "cp b" b8 0x0 (seq (set Z (== (var a) (var b))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var b))) (! (== (cast 4 false (var a)) (cast 4 false (var b)))))) (set C (&& (ule (var a) (var b)) (! (== (var a) (var b))))))
d "cp c" b9 0x0 (seq (set Z (== (var a) (var c))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var c))) (! (== (cast 4 false (var a)) (cast 4 false (var c)))))) (set C (&& (ule (var a) (var c)) (! (== (var a) (var c))))))
d "cp d" ba 0x0 (seq (set Z (== (var a) (var d))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var d))) (! (== (cast 4 false (var a)) (cast 4 false (var d)))))) (set C (&& (ule (var a) (var d)) (! (== (var a) (var d))))))
d "cp e" bb 0x0 (seq (set Z (== (var a) (var e))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var e))) (! (== (cast 4 false (var a)) (cast 4 false (var e)))))) (set C (&& (ule (var a) (var e)) (! (== (var a) (var e))))))
d "cp h" bc 0x0 (seq (set Z (== (var a) (var h))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var h))) (! (== (cast 4 false (var a)) (cast 4 false (var h)))))) (set C (&& (ule (var a) (var h)) (! (== (var a) (var h))))))
d "cp l" bd 0x0 (seq (set Z (== (var a) (var l))) (set N true) (set H (&& (ule (cast 4 false (var a)) (cast 4 false (var l))) (! (== (cast 4 false (var a)) (cast 4 false (var l)))))) (set C (&& (ule (var a) (var l)) (! (== (var a) (var l))))))
d "cpl" 2f 0x0 (seq (set a (~ (var a))) (set N true) (set H true))
d "daa" 27
d "dec [hl]" 35 0x0 (seq (set v (- (load 0 (append (var h) (var l))) (bv 8 0x1))) (store 0 (append (var h) (var l)) (var v)) (set Z (is_zero (var v))) (set N true) (set H (is_zero (cast 4 false (var v)))))
d "dec a" 3d 0x0 (seq (set a (- (var a) (bv 8 0x1))) (set Z (is_zero (var a))) (set N true) (set H (== (cast 4 false (var a)) (bv 4 0xf))))
Expand Down Expand Up @@ -358,15 +358,15 @@ d "ldd a, [hl]" 3a 0x0 (seq (set a (load 0 (append (var h) (var l)))) (set h (it
d "ldi [hl], a" 22 0x0 (seq (store 0 (append (var h) (var l)) (var a)) (set l (+ (var l) (bv 8 0x1))) (set h (ite (is_zero (var l)) (+ (var h) (bv 8 0x1)) (var h))))
d "ldi a, [hl]" 2a 0x0 (seq (set a (load 0 (append (var h) (var l)))) (set l (+ (var l) (bv 8 0x1))) (set h (ite (is_zero (var l)) (+ (var h) (bv 8 0x1)) (var h))))
d "nop" 00 0x0 nop
d "or 0x00" f600
d "or [hl]" b6
d "or a" b7
d "or b" b0
d "or c" b1
d "or d" b2
d "or e" b3
d "or h" b4
d "or l" b5
d "or 0x42" f642 0x0 (seq (set a (| (var a) (bv 8 0x42))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or [hl]" b6 0x0 (seq (set src (load 0 (append (var h) (var l)))) (set a (| (var a) (var src))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or a" b7 0x0 (seq (set a (| (var a) (var a))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or b" b0 0x0 (seq (set a (| (var a) (var b))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or c" b1 0x0 (seq (set a (| (var a) (var c))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or d" b2 0x0 (seq (set a (| (var a) (var d))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or e" b3 0x0 (seq (set a (| (var a) (var e))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or h" b4 0x0 (seq (set a (| (var a) (var h))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "or l" b5 0x0 (seq (set a (| (var a) (var l))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "pop af" f1
d "pop bc" c1
d "pop de" d1
Expand Down Expand Up @@ -605,15 +605,15 @@ d "swap d" cb32
d "swap e" cb33
d "swap h" cb34
d "swap l" cb35
d "xor 0x00" ee00
d "xor [hl]" ae
d "xor a" af
d "xor b" a8
d "xor c" a9
d "xor d" aa
d "xor e" ab
d "xor h" ac
d "xor l" ad
d "xor 0x42" ee42 0x0 (seq (set a (^ (var a) (bv 8 0x42))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor [hl]" ae 0x0 (seq (set src (load 0 (append (var h) (var l)))) (set a (^ (var a) (var src))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor a" af 0x0 (seq (set a (^ (var a) (var a))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor b" a8 0x0 (seq (set a (^ (var a) (var b))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor c" a9 0x0 (seq (set a (^ (var a) (var c))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor d" aa 0x0 (seq (set a (^ (var a) (var d))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor e" ab 0x0 (seq (set a (^ (var a) (var e))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor h" ac 0x0 (seq (set a (^ (var a) (var h))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
d "xor l" ad 0x0 (seq (set a (^ (var a) (var l))) (set Z (is_zero (var a))) (set N false) (set H false) (set C false))
a "ld bc, 0x188" 018801
a "ld de, 0x188" 118801
a "call 0x36e0" cde036

0 comments on commit a5954de

Please sign in to comment.