5 public class OpExpr extends Expr {
11 public void findmatch(Descriptor d, Set s) {
17 public static boolean isInt(Expr e) {
20 if ((e instanceof IntegerLiteralExpr)||
21 ((e instanceof OpExpr)&&(((OpExpr)e).opcode==Opcode.NOP)&&(((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr)))
26 public static int getInt(Expr e) {
27 if (e instanceof IntegerLiteralExpr)
28 return ((IntegerLiteralExpr)e).getValue();
29 else if ((e instanceof OpExpr) && (((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr))
30 return ((IntegerLiteralExpr)((OpExpr)e).getLeftExpr()).getValue();
31 else throw new Error();
34 public OpExpr(Opcode opcode, Expr left, Expr right) {
35 if ((isInt(left)&&isInt(right))||
36 (isInt(left)&&(opcode==Opcode.NOT))||
37 (isInt(left)&&(opcode==Opcode.RND))) {
38 this.opcode=Opcode.NOP;
40 int lint=isInt(left)?getInt(left):0;
41 int rint=isInt(right)?getInt(right):0;
43 if (opcode==Opcode.ADD) {
45 } else if (opcode==Opcode.SUB) {
47 } else if (opcode==Opcode.SHL) {
49 } else if (opcode==Opcode.SHR) {
51 } else if (opcode==Opcode.MULT) {
53 } else if (opcode==Opcode.DIV) {
55 } else if (opcode==Opcode.GT) {
58 } else if (opcode==Opcode.GE) {
61 } else if (opcode==Opcode.LT) {
64 } else if (opcode==Opcode.LE) {
67 } else if (opcode==Opcode.EQ) {
70 } else if (opcode==Opcode.NE) {
73 } else if (opcode==Opcode.AND) {
74 if ((lint!=0)&&(rint!=0))
76 } else if (opcode==Opcode.OR) {
77 if ((lint!=0)||(rint!=0))
79 } else if (opcode==Opcode.NOT) {
82 } else if (opcode==Opcode.RND) {
86 } else throw new Error("Unrecognized Opcode");
87 this.left=new IntegerLiteralExpr(value);
88 } else if ((opcode==Opcode.MULT)&&
89 ((isInt(left)&&(getInt(left)==0))
90 ||(isInt(right)&&(getInt(right)==0)))) {
91 this.opcode=Opcode.NOP;
93 this.left=new IntegerLiteralExpr(0);
98 assert (right == null && (opcode == Opcode.NOT||opcode==Opcode.RND)) || (right != null);
102 public Expr getRightExpr() {
106 public Expr getLeftExpr() {
110 public Set freeVars() {
111 Set lset=left.freeVars();
114 rset=right.freeVars();
122 public String name() {
123 if (opcode==Opcode.NOT)
124 return "!("+left.name()+")";
125 if (opcode==Opcode.NOP)
127 if (opcode==Opcode.RND)
128 return "Round("+left.name()+")";
129 String name=left.name()+opcode.toString();
135 public Opcode getOpcode() {
142 public boolean equals(Map remap, Expr e) {
143 if (e==null||!(e instanceof OpExpr))
146 if (opcode!=oe.opcode)
148 if (!left.equals(remap,oe.left))
150 if ((opcode!=Opcode.NOT)&&(opcode!=Opcode.RND)&&(opcode!=Opcode.NOP))
151 if (!right.equals(remap,oe.right))
156 public DNFRule constructDNF() {
157 if (opcode==Opcode.AND) {
158 DNFRule leftd=left.constructDNF();
159 DNFRule rightd=right.constructDNF();
160 return leftd.and(rightd);
161 } else if (opcode==Opcode.OR) {
162 DNFRule leftd=left.constructDNF();
163 DNFRule rightd=right.constructDNF();
164 return leftd.or(rightd);
165 } else if (opcode==Opcode.NOT) {
166 DNFRule leftd=left.constructDNF();
168 } else return new DNFRule(this);
171 public boolean usesDescriptor(Descriptor d) {
172 if (opcode==Opcode.GT||opcode==Opcode.GE||opcode==Opcode.LT||
173 opcode==Opcode.LE||opcode==Opcode.EQ||opcode==Opcode.NE)
174 return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
175 // return right.usesDescriptor(d);
177 return left.usesDescriptor(d)||(right!=null&&right.usesDescriptor(d));
181 public int[] getRepairs(boolean negated) {
182 if (left instanceof RelationExpr)
183 return new int[] {AbstractRepair.MODIFYRELATION};
184 if (left instanceof SizeofExpr) {
187 /* remove negation through opcode translation */
190 else if (op==Opcode.GE)
192 else if (op==Opcode.EQ)
194 else if (op==Opcode.NE)
196 else if (op==Opcode.LT)
198 else if (op==Opcode.LE)
204 boolean isRelation=((SizeofExpr)left).setexpr instanceof ImageSetExpr;
207 if (((IntegerLiteralExpr)right).getValue()==0)
208 return new int[] {AbstractRepair.REMOVEFROMRELATION};
210 return new int[] {AbstractRepair.ADDTORELATION,
211 AbstractRepair.REMOVEFROMRELATION};
212 } else if (op==Opcode.GE||op==Opcode.GT) {
213 return new int[]{AbstractRepair.ADDTORELATION};
214 } else if (op==Opcode.LE||op==Opcode.LT) {
215 return new int[]{AbstractRepair.REMOVEFROMRELATION};
216 } else if (op==Opcode.NE) {
217 return new int[]{AbstractRepair.ADDTORELATION};
218 } else throw new Error();
221 if (((IntegerLiteralExpr)right).getValue()==0)
222 return new int[] {AbstractRepair.REMOVEFROMSET};
224 return new int[] {AbstractRepair.ADDTOSET,
225 AbstractRepair.REMOVEFROMSET};
226 } else if (op==Opcode.GE||op==Opcode.GT) {
227 return new int[] {AbstractRepair.ADDTOSET};
228 } else if (op==Opcode.LE||op==Opcode.LT) {
229 return new int[] {AbstractRepair.REMOVEFROMSET};
230 } else if (op==Opcode.NE) {
231 return new int[] {AbstractRepair.ADDTOSET};
232 } else throw new Error();
235 throw new Error("BAD");
238 public Descriptor getDescriptor() {
239 return left.getDescriptor();
242 public boolean inverted() {
243 return left.inverted();
246 public Set getInversedRelations() {
247 Set set = left.getInversedRelations();
249 set.addAll(right.getInversedRelations());
254 public Set getRequiredDescriptors() {
255 Set v = left.getRequiredDescriptors();
258 v.addAll(right.getRequiredDescriptors());
264 public void generate(CodeWriter writer, VarDescriptor dest) {
265 VarDescriptor ld = VarDescriptor.makeNew("leftop");
266 left.generate(writer, ld);
267 VarDescriptor rd = null;
268 VarDescriptor lm=VarDescriptor.makeNew("lm");
269 VarDescriptor rm=VarDescriptor.makeNew("rm");
272 if ((opcode==Opcode.OR)||
273 (opcode==Opcode.AND)) {
274 writer.outputline("int "+lm.getSafeSymbol()+"=maybe;");
275 writer.outputline("int maybe=0;");
278 rd = VarDescriptor.makeNew("rightop");
279 right.generate(writer, rd);
283 if (opcode == Opcode.RND) {
284 writer.outputline("int " +dest.getSafeSymbol() + " = (" +
285 ld.getSafeSymbol() + ">>3)<<3; ");
286 writer.outputline("if ("+ld.getSafeSymbol()+" % 8) "+dest.getSafeSymbol()+"+=8;");
287 } else if (opcode == Opcode.NOP) {
288 writer.outputline("int " +dest.getSafeSymbol() + " = " +
289 ld.getSafeSymbol() +"; ");
290 } else if (opcode == Opcode.AND) {
291 writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
292 writer.outputline("maybe = (" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (" + rd.getSafeSymbol() + " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
293 writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " && " + rd.getSafeSymbol() + ";");
294 } else if (opcode == Opcode.OR) {
295 writer.outputline("int "+rm.getSafeSymbol()+"=maybe;");
296 writer.outputline("maybe = (!" + ld.getSafeSymbol() + " && " + rm.getSafeSymbol() + ") || (!" + rd.getSafeSymbol() +
297 " && " + lm.getSafeSymbol() + ") || (" + lm.getSafeSymbol() + " && " + rm.getSafeSymbol() + ");");
298 writer.outputline(dest.getSafeSymbol() + " = " + ld.getSafeSymbol() + " || " + rd.getSafeSymbol() +
300 } else if (opcode != Opcode.NOT) { /* two operands */
302 writer.outputline("int " + dest.getSafeSymbol() + " = " +
303 ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
304 } else if (opcode == Opcode.NOT) {
305 writer.outputline("int " + dest.getSafeSymbol() + " = !" + ld.getSafeSymbol() + ";");
309 public void prettyPrint(PrettyPrinter pp) {
311 if (opcode == Opcode.NOT) {
313 left.prettyPrint(pp);
314 } else if (opcode == Opcode.NOP) {
315 left.prettyPrint(pp);
316 } else if (opcode == Opcode.RND) {
318 left.prettyPrint(pp);
320 left.prettyPrint(pp);
321 pp.output(" " + opcode.toString() + " ");
322 assert right != null;
323 right.prettyPrint(pp);
328 public TypeDescriptor typecheck(SemanticAnalyzer sa) {
329 TypeDescriptor lt = left.typecheck(sa);
330 TypeDescriptor rt = right == null ? null : right.typecheck(sa);
334 } else if (right != null && rt == null) {
340 // #ATTN#: if we want node.next != literal(0) to represent a null check than we need to allow ptr arithmetic
341 // either that or we use a isvalid clause to check for null
344 if (lt != ReservedTypeDescriptor.INT) {
345 sa.getErrorReporter().report(null, "Left hand side of expression is of type '" + lt.getSymbol() + "' but must be type 'int'");
350 if (rt != ReservedTypeDescriptor.INT) {
351 sa.getErrorReporter().report(null, "Right hand side of expression is of type '" + rt.getSymbol() + "' but must be type 'int'");
361 this.td = ReservedTypeDescriptor.INT;