1 /*
2  * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.tools.tree;
27 
28 import sun.tools.java.*;
29 import sun.tools.asm.Assembler;
30 import sun.tools.asm.Label;
31 import java.util.Hashtable;
32 
33 /**
34  * WARNING: The contents of this source file are not part of any
35  * supported API.  Code that depends on them does so at its own risk:
36  * they are subject to change or removal without notice.
37  */
38 public
39 class NotExpression extends UnaryExpression {
40     /**
41      * Constructor
42      */
NotExpression(long where, Expression right)43     public NotExpression(long where, Expression right) {
44         super(NOT, where, Type.tBoolean, right);
45     }
46 
47     /**
48      * Select the type of the expression
49      */
selectType(Environment env, Context ctx, int tm)50     void selectType(Environment env, Context ctx, int tm) {
51         right = convert(env, ctx, Type.tBoolean, right);
52     }
53 
54     /*
55      * Check a "not" expression.
56      *
57      * cvars is modified so that
58      *    cvar.vsTrue indicates variables with a known value if
59      *         the expression is true.
60      *    cvars.vsFalse indicates variables with a known value if
61      *         the expression is false
62      *
63      * For "not" expressions, we look at the inside expression, and then
64      * swap true and false.
65      */
66 
checkCondition(Environment env, Context ctx, Vset vset, Hashtable<Object, Object> exp, ConditionVars cvars)67     public void checkCondition(Environment env, Context ctx, Vset vset,
68                                Hashtable<Object, Object> exp, ConditionVars cvars) {
69         right.checkCondition(env, ctx, vset, exp, cvars);
70         right = convert(env, ctx, Type.tBoolean, right);
71         // swap true and false
72         Vset temp = cvars.vsFalse;
73         cvars.vsFalse = cvars.vsTrue;
74         cvars.vsTrue = temp;
75     }
76 
77     /**
78      * Evaluate
79      */
eval(boolean a)80     Expression eval(boolean a) {
81         return new BooleanExpression(where, !a);
82     }
83 
84     /**
85      * Simplify
86      */
simplify()87     Expression simplify() {
88         // Check if the expression can be optimized
89         switch (right.op) {
90           case NOT:
91             return ((NotExpression)right).right;
92 
93           case EQ:
94           case NE:
95           case LT:
96           case LE:
97           case GT:
98           case GE:
99             break;
100 
101           default:
102             return this;
103         }
104 
105         // Can't negate real comparisons
106         BinaryExpression bin = (BinaryExpression)right;
107         if (bin.left.type.inMask(TM_REAL)) {
108             return this;
109         }
110 
111         // Negate comparison
112         switch (right.op) {
113           case EQ:
114             return new NotEqualExpression(where, bin.left, bin.right);
115           case NE:
116             return new EqualExpression(where, bin.left, bin.right);
117           case LT:
118             return new GreaterOrEqualExpression(where, bin.left, bin.right);
119           case LE:
120             return new GreaterExpression(where, bin.left, bin.right);
121           case GT:
122             return new LessOrEqualExpression(where, bin.left, bin.right);
123           case GE:
124             return new LessExpression(where, bin.left, bin.right);
125         }
126         return this;
127     }
128 
129     /**
130      * Code
131      */
codeBranch(Environment env, Context ctx, Assembler asm, Label lbl, boolean whenTrue)132     void codeBranch(Environment env, Context ctx, Assembler asm, Label lbl, boolean whenTrue) {
133         right.codeBranch(env, ctx, asm, lbl, !whenTrue);
134     }
135 
136     /**
137      * Instead of relying on the default code generation which uses
138      * conditional branching, generate a simpler stream using XOR.
139      */
codeValue(Environment env, Context ctx, Assembler asm)140     public void codeValue(Environment env, Context ctx, Assembler asm) {
141         right.codeValue(env, ctx, asm);
142         asm.add(where, opc_ldc, 1);
143         asm.add(where, opc_ixor);
144     }
145 
146 }
147