From 09d559e4e07c6f766fafbfddbf9212e9d9e7b777 Mon Sep 17 00:00:00 2001 From: Stan Shebs Date: Tue, 29 Dec 2009 23:21:38 +0000 Subject: [PATCH] * ax-gdb.c (gen_expr): Handle logical and, logical or, and conditional expressions. --- gdb/ChangeLog | 5 +++++ gdb/ax-gdb.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3bfe688..1800983 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2009-12-29 Stan Shebs + + * ax-gdb.c (gen_expr): Handle logical and, logical or, and + conditional expressions. + 2009-12-28 Stan Shebs Add trace state variables. diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index ee1f515..34e8128 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -1447,8 +1447,9 @@ gen_expr (struct expression *exp, union exp_element **pc, struct agent_expr *ax, struct axs_value *value) { /* Used to hold the descriptions of operand expressions. */ - struct axs_value value1, value2; + struct axs_value value1, value2, value3; enum exp_opcode op = (*pc)[0].opcode, op2; + int if1, go1, if2, go2, end; /* If we're looking at a constant expression, just push its value. */ { @@ -1488,6 +1489,71 @@ gen_expr (struct expression *exp, union exp_element **pc, gen_expr_binop_rest (exp, op, pc, ax, value, &value1, &value2); break; + case BINOP_LOGICAL_AND: + (*pc)++; + /* Generate the obvious sequence of tests and jumps. */ + gen_expr (exp, pc, ax, &value1); + gen_usual_unary (exp, ax, &value1); + if1 = ax_goto (ax, aop_if_goto); + go1 = ax_goto (ax, aop_goto); + ax_label (ax, if1, ax->len); + gen_expr (exp, pc, ax, &value2); + gen_usual_unary (exp, ax, &value2); + if2 = ax_goto (ax, aop_if_goto); + go2 = ax_goto (ax, aop_goto); + ax_label (ax, if2, ax->len); + ax_const_l (ax, 1); + end = ax_goto (ax, aop_goto); + ax_label (ax, go1, ax->len); + ax_label (ax, go2, ax->len); + ax_const_l (ax, 0); + ax_label (ax, end, ax->len); + value->kind = axs_rvalue; + value->type = language_bool_type (exp->language_defn, exp->gdbarch); + break; + + case BINOP_LOGICAL_OR: + (*pc)++; + /* Generate the obvious sequence of tests and jumps. */ + gen_expr (exp, pc, ax, &value1); + gen_usual_unary (exp, ax, &value1); + if1 = ax_goto (ax, aop_if_goto); + gen_expr (exp, pc, ax, &value2); + gen_usual_unary (exp, ax, &value2); + if2 = ax_goto (ax, aop_if_goto); + ax_const_l (ax, 0); + end = ax_goto (ax, aop_goto); + ax_label (ax, if1, ax->len); + ax_label (ax, if2, ax->len); + ax_const_l (ax, 1); + ax_label (ax, end, ax->len); + value->kind = axs_rvalue; + value->type = language_bool_type (exp->language_defn, exp->gdbarch); + break; + + case TERNOP_COND: + (*pc)++; + gen_expr (exp, pc, ax, &value1); + gen_usual_unary (exp, ax, &value1); + /* For (A ? B : C), it's easiest to generate subexpression + bytecodes in order, but if_goto jumps on true, so we invert + the sense of A. Then we can do B by dropping through, and + jump to do C. */ + gen_logical_not (ax, &value1, + language_bool_type (exp->language_defn, exp->gdbarch)); + if1 = ax_goto (ax, aop_if_goto); + gen_expr (exp, pc, ax, &value2); + gen_usual_unary (exp, ax, &value2); + end = ax_goto (ax, aop_goto); + ax_label (ax, if1, ax->len); + gen_expr (exp, pc, ax, &value3); + gen_usual_unary (exp, ax, &value3); + ax_label (ax, end, ax->len); + /* This is arbitary - what if B and C are incompatible types? */ + value->type = value2.type; + value->kind = value2.kind; + break; + case BINOP_ASSIGN: (*pc)++; if ((*pc)[0].opcode == OP_INTERNALVAR) -- 2.7.4