5 public class OpExpr extends Expr {
11 public void findmatch(Descriptor d, Set s) {
17 public static boolean isInt(Expr e) {
18 if ((e instanceof IntegerLiteralExpr)||
19 ((e instanceof OpExpr)&&(((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr)))
24 public static int getInt(Expr e) {
25 if (e instanceof IntegerLiteralExpr)
26 return ((IntegerLiteralExpr)e).getValue();
27 else if ((e instanceof OpExpr) && (((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr))
28 return ((IntegerLiteralExpr)((OpExpr)e).getLeftExpr()).getValue();
29 else throw new Error();
32 public OpExpr(Opcode opcode, Expr left, Expr right) {
33 if ((isInt(left)&&isInt(right))||
34 (isInt(left)&&(opcode==Opcode.NOT))||
35 (isInt(left)&&(opcode==Opcode.RND))) {
36 this.opcode=Opcode.NOP;
38 int lint=getInt(left);
39 int rint=getInt(right);
41 if (opcode==Opcode.ADD) {
43 } else if (opcode==Opcode.SUB) {
45 } else if (opcode==Opcode.SHL) {
47 } else if (opcode==Opcode.SHR) {
49 } else if (opcode==Opcode.MULT) {
51 } else if (opcode==Opcode.DIV) {
53 } else if (opcode==Opcode.GT) {
56 } else if (opcode==Opcode.GE) {
59 } else if (opcode==Opcode.LT) {
62 } else if (opcode==Opcode.LE) {
65 } else if (opcode==Opcode.EQ) {
68 } else if (opcode==Opcode.NE) {
71 } else if (opcode==Opcode.AND) {
72 if ((lint!=0)&&(rint!=0))
74 } else if (opcode==Opcode.OR) {
75 if ((lint!=0)||(rint!=0))
77 } else if (opcode==Opcode.NOT) {
80 } else if (opcode==Opcode.RND) {
84 } else throw new Error("Unrecognized Opcode");
85 this.left=new IntegerLiteralExpr(value);
90 assert (right == null && (opcode == Opcode.NOT||opcode==Opcode.RND)) || (right != null);
94 public Expr getRightExpr() {
98 public Expr getLeftExpr() {
102 public Set freeVars() {
103 Set lset=left.freeVars();
106 rset=right.freeVars();
114 public String name() {
115 if (opcode==Opcode.NOT)
116 return "!("+left.name()+")";
117 if (opcode==Opcode.NOP)
119 if (opcode==Opcode.RND)
120 return "Round("+left.name()+")";
121 String name=left.name()+opcode.toString();
127 public Opcode getOpcode() {
134 public boolean equals(Map remap, Expr e) {
135 if (e==null||!(e instanceof OpExpr))
138 if (opcode!=oe.opcode)
140 if (!left.equals(remap,oe.left))
142 if ((opcode!=Opcode.NOT)&&(opcode!=Opcode.RND)&&(opcode!=Opcode.NOP))
143 if (!right.equals(remap,oe.right))
148 public DNFRule constructDNF() {
149 if (opcode==Opcode.AND) {
150 DNFRule leftd=left.constructDNF();
151 DNFRule rightd=right.constructDNF();
152 return leftd.and(rightd);
153 } else if (opcode==Opcode.OR) {
154 DNFRule leftd=left.constructDNF();
155 DNFRule rightd=right.constructDNF();
156 return leftd.or(rightd);
157 } else if (opcode==Opcode.NOT) {
158 DNFRule leftd=left.constructDNF();
160 } else return new DNFRule(this);
163 public boolean usesDescriptor(Descriptor d) {
164 if (opcode==Opcode.GT||opcode==Opcode.GE||opcode==Opcode.LT||
165 opcode==Opcode.LE||opcode==Opcode.EQ||opcode==Opcode.NE)
166 return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
167 // return right.usesDescriptor(d);
169 return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
173 public int[] getRepairs(boolean negated) {
174 if (left instanceof RelationExpr)
175 return new int[] {AbstractRepair.MODIFYRELATION};
176 if (left instanceof SizeofExpr) {
179 /* remove negation through opcode translation */
182 else if (op==Opcode.GE)
184 else if (op==Opcode.EQ)
186 else if (op==Opcode.NE)
188 else if (op==Opcode.LT)
190 else if (op==Opcode.LE)
196 boolean isRelation=((SizeofExpr)left).setexpr instanceof ImageSetExpr;
199 if (((IntegerLiteralExpr)right).getValue()==0)
200 return new int[] {AbstractRepair.REMOVEFROMRELATION};
202 return new int[] {AbstractRepair.ADDTORELATION,
203 AbstractRepair.REMOVEFROMRELATION};
204 } else if (op==Opcode.GE||op==Opcode.GT) {
205 return new int[]{AbstractRepair.ADDTORELATION};
206 } else if (op==Opcode.LE||op==Opcode.LT) {
207 return new int[]{AbstractRepair.REMOVEFROMRELATION};
208 } else if (op==Opcode.NE) {
209 return new int[]{AbstractRepair.ADDTORELATION};
210 } else throw new Error();
213 if (((IntegerLiteralExpr)right).getValue()==0)
214 return new int[] {AbstractRepair.REMOVEFROMSET};
216 return new int[] {AbstractRepair.ADDTOSET,
217 AbstractRepair.REMOVEFROMSET};
218 } else if (op==Opcode.GE||op==Opcode.GT) {
219 return new int[] {AbstractRepair.ADDTOSET};
220 } else if (op==Opcode.LE||op==Opcode.LT) {
221 return new int[] {AbstractRepair.REMOVEFROMSET};
222 } else if (op==Opcode.NE) {
223 return new int[] {AbstractRepair.ADDTOSET};
224 } else throw new Error();
227 throw new Error("BAD");
230 public Descriptor getDescriptor() {
231 return left.getDescriptor();
234 public boolean inverted() {
235 return left.inverted();
238 public Set getInversedRelations() {
239 Set set = left.getInversedRelations();
241 set.addAll(right.getInversedRelations());
246 public Set getRequiredDescriptors() {
247 Set v = left.getRequiredDescriptors();
250 v.addAll(right.getRequiredDescriptors());
256 public void generate(CodeWriter writer, VarDescriptor dest) {
257 VarDescriptor ld = VarDescriptor.makeNew("leftop");
258 left.generate(writer, ld);
259 VarDescriptor rd = null;
260 VarDescriptor lm=VarDescriptor.makeNew("lm");
261 VarDescriptor rm=VarDescriptor.makeNew("rm");
264 if ((opcode==Opcode.OR)||
265 (opcode==Opcode.AND)) {
266 writer.outputline("int "+lm.getSafeSymbol()+"=maybe;");
267 writer.outputline("int maybe=0;");
270 rd = VarDescriptor.makeNew("rightop");
271 right.generate(writer, rd);
275 if (opcode == Opcode.RND) {
276 writer.outputline("int " +dest.getSafeSymbol() + " = (" +
277 ld.getSafeSymbol() + ">>3)<<3; ");
278 writer.outputline("if ("+ld.getSafeSymbol()+" % 8) "+dest.getSafeSymbol()+"+=8;");
279 } else if (opcode == Opcode.NOP) {
280 writer.outputline("int " +dest.getSafeSymbol() + " = " +
281 ld.getSafeSymbol() +"; ");
282 } else if (opcode != Opcode.NOT) { /* two operands */
284 writer.outputline("int " + dest.getSafeSymbol() + " = " +
285 ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
286 } else if (opcode == Opcode.AND) {
287 writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
288 writer.outputline("maybe = (" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (" + rd.getSafeSymbol() + " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
289 writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " && " + rd.getSafeSymbol() + ";");
290 } else if (opcode == Opcode.OR) {
291 writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
292 writer.outputline("maybe = (!" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (!" + rd.getSafeSymbol() +
293 " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
294 writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " || " + rd.getSafeSymbol() +
297 writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
301 public void prettyPrint(PrettyPrinter pp) {
303 if (opcode == Opcode.NOT) {
305 left.prettyPrint(pp);
306 } else if (opcode == Opcode.NOP) {
307 left.prettyPrint(pp);
308 } else if (opcode == Opcode.RND) {
310 left.prettyPrint(pp);
312 left.prettyPrint(pp);
313 pp.output(" " + opcode.toString() + " ");
314 assert right != null;
315 right.prettyPrint(pp);
320 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
321 TypeDescriptor lt = left.typecheck(sa);
322 TypeDescriptor rt = right == null ? null : right.typecheck(sa);
326 } else if (right != null && rt == null) {
332 // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
333 // either that or we use a isvalid clause to check for null
336 if (lt != ReservedTypeDescriptor.INT) {
337 sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
342 if (rt != ReservedTypeDescriptor.INT) {
343 sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
353 this.td = ReservedTypeDescriptor.INT;