From 79232f46d87d9da159514270c6e1586077f26f86 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 24 Nov 2007 20:32:35 -0800 Subject: [PATCH] Proper signedness of comparison operands Comparison operands are signed only of both operands are signed. If one is unsigned, then they both are unsigned. This does not affect the signedness of the comparison itself, which is unsigned. Signed-off-by: Stephen Williams --- PExpr.h | 2 ++ elab_expr.cc | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/PExpr.h b/PExpr.h index b1d8b34ea..37c215fb7 100644 --- a/PExpr.h +++ b/PExpr.h @@ -525,6 +525,8 @@ class PEBinary : public PExpr { NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const; NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const; + static void surpress_operand_sign_if_needed_(NetExpr*lp, NetExpr*rp); + private: NetNet* elaborate_net_add_(Design*des, NetScope*scope, unsigned lwidth, diff --git a/elab_expr.cc b/elab_expr.cc index cf4470b93..a040d1b7e 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -111,6 +111,20 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, return tmp; } +void PEBinary::surpress_operand_sign_if_needed_(NetExpr*lp, NetExpr*rp) +{ + // If either operand is unsigned, then treat the whole + // expression as unsigned. This test needs to be done hear + // instead of in *_expr_base_ because it needs to be done + // ahead of any subexpression evaluation (because they need to + // know their signedness to evaluate) and because there are + // exceptions to this rule. + if (! lp->has_sign()) + rp->cast_signed(false); + if (! rp->has_sign()) + lp->cast_signed(false); +} + NetEBinary* PEBinary::elaborate_eval_expr_base_(Design*des, NetExpr*lp, NetExpr*rp, @@ -296,6 +310,8 @@ NetEBinary* PEBComp::elaborate_expr(Design*des, NetScope*scope, return 0; } + surpress_operand_sign_if_needed_(lp, rp); + return elaborate_eval_expr_base_(des, lp, rp, use_wid); }