AstNode* newSubNeg(AstNode* lhsp, vlsint32_t rhs) { // Return lhs-rhs, but if rhs is negative use an add, so we won't // have to deal with signed math and related 32bit sign extension problems if (rhs == 0) { return lhsp; } else if (lhsp->castConst()) { // Optional vs just making add/sub below, but saves constification some work V3Number num (lhsp->fileline(), lhsp->width()); num.opSub(lhsp->castConst()->num(), V3Number(lhsp->fileline(), 32, rhs)); num.isSigned(lhsp->isSigned()); AstNode* newp = new AstConst(lhsp->fileline(), num); return newp; } else if (rhs > 0) { AstNode* newp = new AstSub(lhsp->fileline(), lhsp, new AstConst(lhsp->fileline(), AstConst::Unsized32(), rhs)); // We must make sure sub gets sign of original value, not from the constant newp->dtypeFrom(lhsp); return newp; } else { // rhs < 0; AstNode* newp = new AstAdd(lhsp->fileline(), lhsp, new AstConst(lhsp->fileline(), AstConst::Unsized32(), -rhs)); // We must make sure sub gets sign of original value, not from the constant newp->dtypeFrom(lhsp); return newp; } }
void test(string lhss, string op, string rhss, string exps) { char* l1 = strdup(lhss.c_str()); char* r1 = strdup(rhss.c_str()); char* e1 = strdup(exps.c_str()); V3Number lhnum (new FileLine ("ck",__LINE__), l1); V3Number rhnum (new FileLine ("ck",__LINE__), r1); V3Number expnum (new FileLine("ck",__LINE__), e1); V3Number gotnum (new FileLine("ck",__LINE__), expnum.width()); if (op=="redOr") gotnum.opRedOr (lhnum); else if (op=="redAnd") gotnum.opRedAnd (lhnum); else if (op=="redXor") gotnum.opRedXor (lhnum); else if (op=="redXnor") gotnum.opRedXnor (lhnum); else if (op=="concat") gotnum.opConcat (lhnum,rhnum); else if (op=="repl") gotnum.opRepl (lhnum,rhnum); else if (op=="~") gotnum.opNot (lhnum); else if (op=="!") gotnum.opLogNot (lhnum); else if (op=="negate") gotnum.opNegate (lhnum); else if (op=="+") gotnum.opAdd (lhnum,rhnum); else if (op=="-") gotnum.opSub (lhnum,rhnum); else if (op=="*") gotnum.opMul (lhnum,rhnum); else if (op=="/") gotnum.opDiv (lhnum,rhnum); else if (op=="%") gotnum.opModDiv (lhnum,rhnum); else if (op=="&") gotnum.opAnd (lhnum,rhnum); else if (op=="|") gotnum.opOr (lhnum,rhnum); else if (op=="<") gotnum.opLt (lhnum,rhnum); else if (op==">") gotnum.opGt (lhnum,rhnum); else if (op==">>") gotnum.opShiftR (lhnum,rhnum); else if (op=="<<") gotnum.opShiftL (lhnum,rhnum); else if (op=="==") gotnum.opEq (lhnum,rhnum); else if (op=="===") gotnum.opCaseEq (lhnum,rhnum); else if (op=="==?") gotnum.opWildEq (lhnum,rhnum); else if (op=="!=") gotnum.opNeq (lhnum,rhnum); else if (op=="!==") gotnum.opCaseNeq (lhnum,rhnum); else if (op=="!=?") gotnum.opWildNeq (lhnum,rhnum); else if (op=="<=") gotnum.opLte (lhnum,rhnum); else if (op==">=") gotnum.opGte (lhnum,rhnum); else if (op=="&&") gotnum.opLogAnd (lhnum,rhnum); else if (op=="||") gotnum.opLogOr (lhnum,rhnum); else v3fatalSrc("Bad opcode: "<<op); UINFO(0,"------- Test:\n" <<" "<<lhnum<<" "<<op<<endl <<" "<<rhnum<<endl <<" = "<<expnum<<endl <<" =? "<<gotnum<<endl); V3Number ok (new FileLine("ck",__LINE__), 1); ok.opCaseEq(expnum,gotnum); if (ok.toUInt()!=1) { v3fatalSrc("%Error:Test FAILED\n"); } }