char* CompiledLoop::checkLoopVar() { #ifdef unnecessary // first check if loop var is initialized to lower bound BB* beforeLoopBB = _beforeLoop->bb(); // search for assignment preceeding loop for (Node* n = _beforeLoop; n && n->bb() == beforeLoopBB && (!n->isAssignNode() || ((AssignNode*)n)->dest() != loopVar); n = n->firstPrev()) ; if (n && n->bb() == beforeLoopBB) { // ok, found the assignment assert(n->isAssignNode() && ((AssignNode*)n)->dest() == loopVar, "oops"); } else { return "no lower-bound assignment to loop var before loop"; } #endif // check usage of loop var within loop // quick check: must have at least 2 defs (initialization plus increment) if (_loopVar->isSinglyAssigned()) return "loopVar has single definition globally"; // loop variable must have exactly one def in loop, and def must be result of an addition // usual code pattern: SAPn = add(loopVar, const); ...; loopVar := SAPn if (defsInLoop(_loopVar) != 1) return "loopVar has != 1 defs in loop"; NonTrivialNode* n1 = findDefInLoop(_loopVar); if (defsInLoop(n1->src()) != 1) return "loopVar has != 1 defs in loop (2)"; NonTrivialNode* n2 = findDefInLoop(n1->src()); PReg* operand; ArithOpCode op; if (n2->isTArithNode()) { operand = ((TArithRRNode*)n2)->operand(); op = ((TArithRRNode*)n2)->op(); } else if (n2->isArithNode()) { operand = ((ArithRRNode*)n2)->operand(); op = ((ArithRRNode*)n2)->op(); } else { return "loopVar def not an arithmetic operation"; } _incNode = n2; if (op != tAddArithOp && op != tSubArithOp) return "loopVar def isn't an add/sub"; if (_incNode->src() == _loopVar) { if (!isIncrement(operand, op)) return "loopVar isn't incremented by constant/loop-invariant"; } else if (operand == _loopVar) { if (!isIncrement(_incNode->src(), op)) return "loopVar isn't incremented by constant/loop-invariant"; } else { return "loopVar def isn't an increment"; } // at this point, we finally know for sure whether the loop is counting up or down // check that loop is bounded at all BranchOpCode branchOp = _loopBranch->op(); bool loopVarMustBeLeft = (branchOp == GTBranchOp || branchOp == GEBranchOp) ^ !_isCountingUp; NonTrivialNode* compare = (NonTrivialNode*)_loopBranch->firstPrev(); if (loopVarMustBeLeft != (compare->src() == _loopVar)) { return "loopVar is on wrong side of comparison (loop not bounded)"; } return NULL; }
/* NumberTextCtrl::getDecNumber * Returns the number currently entered. If it's an incrememt or * decrement, returns [base] incremented/decremented by the number *******************************************************************/ double NumberTextCtrl::getDecNumber(double base) { // If decimals aren't allowed just return truncated integral value if (!allow_decimal) return getNumber(base); string val = GetValue(); // Get double value double dval; if (val.IsEmpty()) return 0; else if (val.StartsWith("--") || val.StartsWith("++")) val = val.Mid(2); else if (val.StartsWith("+")) val = val.Mid(1); val.ToDouble(&dval); // Return it (incremented/decremented based on [base]) if (isIncrement()) return base + dval; else if (isDecrement()) return base - dval; else return dval; }
/* NumberTextCtrl::getNumber * Returns the number currently entered. If it's an incrememt or * decrement, returns [base] incremented/decremented by the number *******************************************************************/ int NumberTextCtrl::getNumber(int base) { string val = GetValue(); // Get integer value long lval; if (val.IsEmpty()) return 0; else if (val.StartsWith("--") || val.StartsWith("++") || val.StartsWith("**") || val.StartsWith("//")) val = val.Mid(2); else if (val.StartsWith("+") || val.StartsWith("*") || val.StartsWith("/")) val = val.Mid(1); val.ToLong(&lval); // Return it (incremented/decremented based on [base]) if (isIncrement()) return base + lval; else if (isDecrement()) return base - lval; else if (isFactor()) return base * lval; else if (isDivisor()) return base / lval; else return lval; }