public override bool Equals(object obj) { OpCodeConst op = obj as OpCodeConst; if (op == null) { return(false); } Eval(false); // Ensure we have the current state op.Eval(false); return(State == op.State); }
/// <summary> /// Embed wires and constant wires /// </summary> OpCode EmbedWires(List <OpCodeExpr> expressions, OpCode op, int minOpt) { // Recurse down the expression tree if (op.Operands != null) { for (int i = 0; i < op.Operands.Count; i++) { op.Operands[i] = EmbedWires(expressions, op.Operands[i], minOpt); } } // Replace only terminal OpCodeTerminal term = op as OpCodeTerminal; if (term == null) { return(op); } // Replace wire expressions (if the wire doesn't point outside of minOpt) OpCodeTerminal wire = term.Expression.Expr as OpCodeTerminal; if (wire != null && term.Expression.Index >= minOpt) { // Replace this terminal with the wire's target // (i.e. follow the wire) term.Negate ^= wire.Negate; term.Expression = wire.Expression; mWires++; return(term); } // Replace constant expressions OpCodeConst constTerm = term.Expression.Expr as OpCodeConst; if (constTerm != null) { constTerm.Eval(true); if (constTerm.State == OpState.Zero || constTerm.State == OpState.One) { mConstWires++; return(new OpCodeConst(((int)term.Negate ^ (int)constTerm.State) & 1)); } } return(term); }
/// <summary> /// Non recursively remove constants: /// A * 1 = A /// A + 0 = A /// A # 0 = A /// A # 1 = !A /// A * 0 = 0 /// A + 1 = 1 /// </summary> public static OpCode RemoveConstNR(OpCodeMath op, ref int removeConst, ref int removeConstExpr, ref int removeUnary) { // Remove all constants Type opType = op.GetType(); for (int i = 0; i < op.Operands.Count; i++) { // Must leave atleast one operand to know the value if (op.Operands.Count <= 1) { break; } // Skip non-constant values OpCodeConst constTerm = op.Operands[i] as OpCodeConst; if (constTerm == null) { continue; // Skip non-constants } constTerm.Eval(true); // Ensure Negate is not set if (constTerm.State != OpState.Zero && constTerm.State != OpState.One) { continue; // Skip non-boolean states } // Remove constant: // A * 1 = A // A + 0 = A // A # 0 = A // A # 1 = !A if (opType == typeof(OpCodeXor) || opType == typeof(OpCodeAnd) && constTerm.State == OpState.One || opType == typeof(OpCodeOr) && constTerm.State == OpState.Zero) { // Check for (A # 1) = !A if (opType == typeof(OpCodeXor) && constTerm.State == OpState.One) { op.Negate ^= OpState.One; } // Remove constant op.Operands.RemoveAt(i); i--; // Retry this operand removeConst++; continue; // Continue processing all operands } // Remove constant: // A * 0 = 0 // A + 1 = 1 if (opType == typeof(OpCodeAnd) && constTerm.State == OpState.Zero || opType == typeof(OpCodeOr) && constTerm.State == OpState.One) { // Remove entire sub-expression op.Operands.Clear(); op.Operands.Add(constTerm); removeConstExpr++; break; // Done with all processing } } // Check for only one operand if (op.Operands.Count == 1) { // Remove this gate, and return the operand. // AND, OR, XOR = nop. NAND, NOR, XNOR = inverter. removeUnary++; op.Operands[0].Negate ^= op.Negate; return(op.Operands[0]); } return(op); }