writer.outputline("int " + dest.getSafeSymbol() +
" = " + ptr + "(" + leftd.getSafeSymbol() + " + " + offset.getSafeSymbol() + ");");
dotypecheck = true;
- }
+ }
}
Expr right;
Opcode opcode;
- public OpExpr(Opcode opcode, Expr left, Expr right) {
- this.opcode = opcode;
- this.left = left;
- this.right = right;
+ public static boolean isInt(Expr e) {
+ if ((e instanceof IntegerLiteralExpr)||
+ ((e instanceof OpExpr)&&(((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr)))
+ return true;
+ return false;
+ }
- assert (right == null && opcode == Opcode.NOT) || (right != null);
+ public static int getInt(Expr e) {
+ if (e instanceof IntegerLiteralExpr)
+ return ((IntegerLiteralExpr)e).getValue();
+ else if ((e instanceof OpExpr) && (((OpExpr)e).getLeftExpr() instanceof IntegerLiteralExpr))
+ return ((IntegerLiteralExpr)((OpExpr)e).getLeftExpr()).getValue();
+ else throw new Error();
+ }
+
+ public OpExpr(Opcode opcode, Expr left, Expr right) {
+ if ((isInt(left)&&isInt(right))||
+ (isInt(left)&&(opcode==Opcode.NOT))||
+ (isInt(left)&&(opcode==Opcode.RND))) {
+ this.opcode=Opcode.NOP;
+ this.right=null;
+ int lint=getInt(left);
+ int rint=getInt(right);
+ int value=0;
+ if (opcode==Opcode.ADD) {
+ value=lint+rint;
+ } else if (opcode==Opcode.SUB) {
+ value=lint-rint;
+ } else if (opcode==Opcode.SHL) {
+ value=lint<<rint;
+ } else if (opcode==Opcode.SHR) {
+ value=lint>>rint;
+ } else if (opcode==Opcode.MULT) {
+ value=lint*rint;
+ } else if (opcode==Opcode.DIV) {
+ value=lint/rint;
+ } else if (opcode==Opcode.GT) {
+ if (lint>rint)
+ value=1;
+ } else if (opcode==Opcode.GE) {
+ if (lint>=rint)
+ value=1;
+ } else if (opcode==Opcode.LT) {
+ if (lint<rint)
+ value=1;
+ } else if (opcode==Opcode.LE) {
+ if (lint<=rint)
+ value=1;
+ } else if (opcode==Opcode.EQ) {
+ if (lint==rint)
+ value=1;
+ } else if (opcode==Opcode.NE) {
+ if (lint!=rint)
+ value=1;
+ } else if (opcode==Opcode.AND) {
+ if ((lint!=0)&&(rint!=0))
+ value=1;
+ } else if (opcode==Opcode.OR) {
+ if ((lint!=0)||(rint!=0))
+ value=1;
+ } else if (opcode==Opcode.NOT) {
+ if (lint==0)
+ value=1;
+ } else if (opcode==Opcode.RND) {
+ value=((lint>>3)<<3);
+ if ((lint % 8)!=0)
+ value+=8;
+ } else throw new Error("Unrecognized Opcode");
+ this.left=new IntegerLiteralExpr(value);
+ } else {
+ this.opcode = opcode;
+ this.left = left;
+ this.right = right;
+ assert (right == null && (opcode == Opcode.NOT||opcode==Opcode.RND)) || (right != null);
+ }
}
public Expr getRightExpr() {
public String name() {
if (opcode==Opcode.NOT)
return "!("+left.name()+")";
+ if (opcode==Opcode.NOP)
+ return left.name();
+ if (opcode==Opcode.RND)
+ return "Round("+left.name()+")";
String name=left.name()+opcode.toString();
if (right!=null)
name+=right.name();
return false;
if (!left.equals(remap,oe.left))
return false;
- if (opcode!=Opcode.NOT)
+ if ((opcode!=Opcode.NOT)&&(opcode!=Opcode.RND)&&(opcode!=Opcode.NOP))
if (!right.equals(remap,oe.right))
return false;
return true;
}
String code;
- if (opcode != Opcode.NOT) { /* two operands */
+ if (opcode == Opcode.RND) {
+ writer.outputline("int " +dest.getSafeSymbol() + " = (" +
+ ld.getSafeSymbol() + ">>3)<<3; ");
+ writer.outputline("if ("+ld.getSafeSymbol()+" % 8) "+dest.getSafeSymbol()+"+=8;");
+ } else if (opcode == Opcode.NOP) {
+ writer.outputline("int " +dest.getSafeSymbol() + " = " +
+ ld.getSafeSymbol() +"; ");
+ } else if (opcode != Opcode.NOT) { /* two operands */
assert rd != null;
writer.outputline("int " + dest.getSafeSymbol() + " = " +
ld.getSafeSymbol() + " " + opcode.toString() + " " + rd.getSafeSymbol() + ";");
public void prettyPrint(PrettyPrinter pp) {
pp.output("(");
if (opcode == Opcode.NOT) {
+ pp.output("!");
+ left.prettyPrint(pp);
+ } else if (opcode == Opcode.NOP) {
+ left.prettyPrint(pp);
+ } else if (opcode == Opcode.RND) {
+ pp.output("RND ");
left.prettyPrint(pp);
} else {
left.prettyPrint(pp);
public static final Opcode AND = new Opcode("&&");
public static final Opcode OR = new Opcode("||");
public static final Opcode NOT = new Opcode("!");
+ public static final Opcode RND = new Opcode("RND");
+ public static final Opcode NOP = new Opcode("NOP");
+ public static final Opcode SHL = new Opcode("<<");
+ public static final Opcode SHR = new Opcode(">>");
public static Opcode decodeFromString(String opname) {
Opcode opcode;
String repairtable="repairtable";
String left="left";
String right="right";
+ /* Rewrite globals */
+
+ for (Iterator it=this.state.stGlobals.descriptors();it.hasNext();) {
+ VarDescriptor vd=(VarDescriptor)it.next();
+ craux.outputline("#define "+vd.getSafeSymbol()+" "+state+"->"+vd.getSafeSymbol());
+ }
+
for(Iterator it=termination.updatenodes.iterator();it.hasNext();) {
GraphNode gn=(GraphNode) it.next();
TermNode tn=(TermNode) gn.getOwner();
craux.outputline("void "+methodname+"("+name+"_state * "+state+","+name+" * "+model+", RepairHash * "+repairtable+", int "+left+")");
}
craux.startblock();
- un.generate(craux, false, left,right);
+ final SymbolTable st = un.getRule().getSymbolTable();
+ CodeWriter cr = new StandardCodeWriter(outputaux) {
+ public SymbolTable getSymbolTable() { return st; }
+ };
+ un.generate(cr, false, left,right);
craux.endblock();
break;
case MultUpdateNode.REMOVE:
crhead.outputline(methodcall+";");
craux.outputline(methodcall);
craux.startblock();
- un.generate(craux, true, null,null);
+ final SymbolTable st2 = un.getRule().getSymbolTable();
+ CodeWriter cr2 = new StandardCodeWriter(outputaux) {
+ public SymbolTable getSymbolTable() { return st2; }
+ };
+ un.generate(cr2, true, null,null);
craux.endblock();
break;
case MultUpdateNode.MODIFY:
return fields.keys();
}
- private Vector getFieldSizes() {
- Vector fieldsizes = new Vector();
-
+
+ public Expr getSizeExpr() {
+ return getOffsetExpr(null);
+ }
+
+ public Expr getOffsetExpr(FieldDescriptor field) {
+
+ boolean aligned=true;
+ Expr size = new IntegerLiteralExpr(0);
+
for (int i = 0; i < fieldlist.size(); i++) {
- FieldDescriptor fd = (FieldDescriptor) fieldlist.elementAt(i);
+ FieldDescriptor fd = (FieldDescriptor)fieldlist.elementAt(i);
+
TypeDescriptor td = fd.getType();
boolean ptr = fd.getPtr();
-
Expr basesize;
if (ptr) { /* ptrs are 32bits */
- basesize = new IntegerLiteralExpr(32);
+
+ basesize = new IntegerLiteralExpr(32);
} else {
- basesize = td.getSizeExpr();
+ basesize = td.getSizeExpr();
}
-
+ Expr fieldsize;
if (fd instanceof ArrayDescriptor) {
Expr totalsize = new OpExpr(Opcode.MULT, basesize, ((ArrayDescriptor) fd).getIndexBound());
- fieldsizes.addElement(totalsize);
+ fieldsize=totalsize;
} else {
- fieldsizes.addElement(basesize);
+ fieldsize=basesize;
}
- }
-
- return fieldsizes;
- }
-
- public Expr getSizeExpr() {
- Vector fieldsizes = getFieldSizes();
-
- /* we've got the field sizes! now return the addition! */
- Expr size = new IntegerLiteralExpr(0);
-
- for (int i = 0; i < fieldsizes.size(); i++) {
- Expr fieldsize = (Expr) fieldsizes.elementAt(i);
- size = new OpExpr(Opcode.ADD, fieldsize, size);
- }
-
- return size;
- }
-
- public Expr getOffsetExpr(FieldDescriptor field) {
- Vector fieldsizes = getFieldSizes();
-
- // #ATTN#: getOffsetExpr needs to be called with the fielddescriptor obect that is in teh vector list
- // this means that if the field is an arraydescriptor you have to call getOffsetExpr with the array
-
- /* we've got the field sizes! now return the addition! */
- Expr size = new IntegerLiteralExpr(0);
-
- for (int i = 0; i < fieldsizes.size(); i++) {
- FieldDescriptor fd = (FieldDescriptor)fieldlist.elementAt(i);
+ if (td instanceof ReservedTypeDescriptor) {
+ ReservedTypeDescriptor rtd=(ReservedTypeDescriptor) td;
+ if (rtd==ReservedTypeDescriptor.BIT) {
+ aligned=false;
+ } else {
+ if (!aligned) {
+ size=new OpExpr(Opcode.RND, size,null);
+ aligned=true;
+ }
+ }
+ } else {
+ if (!aligned) {
+ size=new OpExpr(Opcode.RND, size,null);
+ aligned=true;
+ }
+ }
if (fd == field) { /* stop, reached target field */
break;
}
- Expr fieldsize = (Expr) fieldsizes.elementAt(i);
size = new OpExpr(Opcode.ADD, fieldsize, size);
}
-
+
+ if ((field==null)&&(!aligned))
+ return new OpExpr(Opcode.RND, size, null);
return size;
}
cr.outputline(vd.getSafeSymbol()+"="+right.getSafeSymbol()+";");
} else if (u.isField()) {
/* NEED TO FIX */
+ Expr subexpr=((DotExpr)u.getLeftExpr()).getExpr();
+ Expr intindex=((DotExpr)u.getLeftExpr()).getIndex();
+ VarDescriptor subvd=VarDescriptor.makeNew("subexpr");
+ VarDescriptor indexvd=VarDescriptor.makeNew("index");
+ subexpr.generate(cr,subvd);
+ if (intindex!=null)
+ intindex.generate(cr,indexvd);
+ FieldDescriptor fd=(FieldDescriptor)u.getDescriptor();
+ StructureTypeDescriptor std=(StructureTypeDescriptor)subexpr.getType();
+ if (fd instanceof ArrayDescriptor) {
+ fd = ((ArrayDescriptor) fd).getField();
+ }
+
+ Expr offsetbits = std.getOffsetExpr(fd);
+ if (intindex != null) {
+ Expr basesize = fd.getBaseSizeExpr();
+ offsetbits = new OpExpr(Opcode.ADD, offsetbits, new OpExpr(Opcode.MULT, basesize, intindex));
+ }
+ Expr offsetbytes = new OpExpr(Opcode.SHR, offsetbits,new IntegerLiteralExpr(3));
+ Expr byteaddress=new OpExpr(Opcode.ADD, offsetbytes, subexpr);
+ VarDescriptor addr=VarDescriptor.makeNew("byteaddress");
+ byteaddress.generate(cr,addr);
+
+ if (fd.getType() instanceof ReservedTypeDescriptor && !fd.getPtr()) {
+ ReservedTypeDescriptor rtd=(ReservedTypeDescriptor)fd.getType();
+ if (rtd==ReservedTypeDescriptor.INT) {
+ cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ } else if (rtd==ReservedTypeDescriptor.SHORT) {
+ cr.outputline("*((short *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ } else if (rtd==ReservedTypeDescriptor.BYTE) {
+ cr.outputline("*((char *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ } else if (rtd==ReservedTypeDescriptor.BIT) {
+ Expr tmp = new OpExpr(Opcode.SHL, offsetbytes, new IntegerLiteralExpr(3));
+ Expr offset=new OpExpr(Opcode.SUB, offsetbits, tmp);
+ Expr mask=new OpExpr(Opcode.SHR, new IntegerLiteralExpr(1), offset);
+ VarDescriptor maskvar=VarDescriptor.makeNew("mask");
+ mask.generate(cr,maskvar);
+ cr.outputline("*((char *) "+addr.getSafeSymbol()+")|="+maskvar.getSafeSymbol()+";");
+ cr.outputline("if (!"+right.getSafeSymbol()+")");
+ cr.outputline("*((char *) "+addr.getSafeSymbol()+")^="+maskvar.getSafeSymbol()+";");
+ } else throw new Error();
+ } else {
+ /* Pointer */
+ cr.outputline("*((int *) "+addr.getSafeSymbol()+")="+right.getSafeSymbol()+";");
+ }
}
cr.endblock();
-
}
}
+
+ private int bitmask(int bits) {
+ int mask = 0;
+
+ for (int i = 0; i < bits; i++) {
+ mask <<= 1;
+ mask += 1;
+ }
+
+ return mask;
+ }
+
private void generate_bindings(CodeWriter cr, String slot0, String slot1) {
for(int i=0;i<bindings.size();i++) {
Binding b=(Binding)bindings.get(i);