// // Connect two nodes with a new parent that does a binary operation on the nodes. // // Returns the added node. // TIntermTyped *TIntermediate::addBinaryMath( TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line) { // // Need a new node holding things together then. Make // one and promote it to the right type. // TIntermBinary *node = new TIntermBinary(op); node->setLine(line); node->setLeft(left); node->setRight(right); if (!node->promote(mInfoSink)) return NULL; // // See if we can fold constants. // TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); if (leftTempConstant && rightTempConstant) { TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, mInfoSink); if (typedReturnNode) return typedReturnNode; } return node; }
// // Add one node as the parent of another that it operates on. // // Returns the added node. // TIntermTyped *TIntermediate::addUnaryMath( TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType) { TIntermConstantUnion *childTempConstant = 0; if (child->getAsConstantUnion()) childTempConstant = child->getAsConstantUnion(); // // Make a new node for the operator. // TIntermUnary *node = new TIntermUnary(op); node->setLine(line); node->setOperand(child); node->promote(funcReturnType); if (childTempConstant) { TIntermTyped *newChild = childTempConstant->fold(op, nullptr, mInfoSink); if (newChild) return newChild; } return node; }
// // Add one node as the parent of another that it operates on. // // Returns the added node. // TIntermTyped *TIntermediate::addUnaryMath( TOperator op, TIntermTyped *child, const TSourceLoc &line) { TIntermConstantUnion *childTempConstant = 0; if (child->getAsConstantUnion()) childTempConstant = child->getAsConstantUnion(); // // Make a new node for the operator. // TIntermUnary *node = new TIntermUnary(op); node->setLine(line); node->setOperand(child); if (!node->promote(mInfoSink)) return 0; switch (op) { case EOpFloatBitsToInt: case EOpFloatBitsToUint: case EOpIntBitsToFloat: case EOpUintBitsToFloat: case EOpPackSnorm2x16: case EOpPackUnorm2x16: case EOpPackHalf2x16: case EOpUnpackSnorm2x16: case EOpUnpackUnorm2x16: node->getTypePointer()->setPrecision(EbpHigh); break; case EOpUnpackHalf2x16: node->getTypePointer()->setPrecision(EbpMedium); break; default: break; } if (childTempConstant) { TIntermTyped *newChild = childTempConstant->fold(op, 0, mInfoSink); if (newChild) return newChild; } return node; }
// // Connect two nodes with a new parent that does a binary operation on the nodes. // // Returns the added node. // TIntermTyped *TIntermediate::addBinaryMath( TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line) { switch (op) { case EOpEqual: case EOpNotEqual: if (left->isArray()) return NULL; break; case EOpLessThan: case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) { return NULL; } break; case EOpLogicalOr: case EOpLogicalXor: case EOpLogicalAnd: if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) { return NULL; } break; case EOpAdd: case EOpSub: case EOpDiv: case EOpMul: if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) return NULL; default: break; } if (left->getBasicType() != right->getBasicType()) { return NULL; } // // Need a new node holding things together then. Make // one and promote it to the right type. // TIntermBinary *node = new TIntermBinary(op); node->setLine(line); node->setLeft(left); node->setRight(right); if (!node->promote(mInfoSink)) return NULL; // // See if we can fold constants. // TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); if (leftTempConstant && rightTempConstant) { TIntermTyped *typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, mInfoSink); if (typedReturnNode) return typedReturnNode; } return node; }
// // Add one node as the parent of another that it operates on. // // Returns the added node. // TIntermTyped *TIntermediate::addUnaryMath( TOperator op, TIntermNode *childNode, const TSourceLoc &line) { TIntermUnary *node; TIntermTyped *child = childNode->getAsTyped(); if (child == NULL) { mInfoSink.info.message(EPrefixInternalError, line, "Bad type in AddUnaryMath"); return NULL; } switch (op) { case EOpLogicalNot: if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) { return NULL; } break; case EOpPostIncrement: case EOpPreIncrement: case EOpPostDecrement: case EOpPreDecrement: case EOpNegative: case EOpPositive: if (child->getType().getBasicType() == EbtStruct || child->getType().isArray()) { return NULL; } default: break; } TIntermConstantUnion *childTempConstant = 0; if (child->getAsConstantUnion()) childTempConstant = child->getAsConstantUnion(); // // Make a new node for the operator. // node = new TIntermUnary(op); node->setLine(line); node->setOperand(child); if (!node->promote(mInfoSink)) return 0; if (childTempConstant) { TIntermTyped *newChild = childTempConstant->fold(op, 0, mInfoSink); if (newChild) return newChild; } return node; }
// // Add one node as the parent of another that it operates on. // // Returns the added node. // TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable) { TIntermUnary* node; TIntermTyped* child = childNode->getAsTyped(); if (child == 0) { infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line); return 0; } switch (op) { case EOpLogicalNot: if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) { return 0; } break; case EOpPostIncrement: case EOpPreIncrement: case EOpPostDecrement: case EOpPreDecrement: case EOpNegative: if (child->getType().getBasicType() == EbtStruct || child->getType().isArray()) return 0; default: break; } // // Do we need to promote the operand? // // Note: Implicit promotions were removed from the language. // TBasicType newType = EbtVoid; switch (op) { case EOpConstructInt: newType = EbtInt; break; case EOpConstructBool: newType = EbtBool; break; case EOpConstructFloat: newType = EbtFloat; break; default: break; } if (newType != EbtVoid) { child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary, child->getNominalSize(), child->isMatrix(), child->isArray()), child); if (child == 0) return 0; } // // For constructors, we are now done, it's all in the conversion. // switch (op) { case EOpConstructInt: case EOpConstructBool: case EOpConstructFloat: return child; default: break; } TIntermConstantUnion *childTempConstant = 0; if (child->getAsConstantUnion()) childTempConstant = child->getAsConstantUnion(); // // Make a new node for the operator. // node = new TIntermUnary(op); if (line == 0) line = child->getLine(); node->setLine(line); node->setOperand(child); if (! node->promote(infoSink)) return 0; if (childTempConstant) { TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink); if (newChild) return newChild; } return node; }
// // Connect two nodes with a new parent that does a binary operation on the nodes. // // Returns the added node. // TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable) { switch (op) { case EOpEqual: case EOpNotEqual: if (left->isArray()) return 0; break; case EOpLessThan: case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) { return 0; } break; case EOpLogicalOr: case EOpLogicalXor: case EOpLogicalAnd: if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) { return 0; } break; case EOpAdd: case EOpSub: case EOpDiv: case EOpMul: if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) return 0; default: break; } // // First try converting the children to compatible types. // if (left->getType().getStruct() && right->getType().getStruct()) { if (left->getType() != right->getType()) return 0; } else { TIntermTyped* child = addConversion(op, left->getType(), right); if (child) right = child; else { child = addConversion(op, right->getType(), left); if (child) left = child; else return 0; } } // // Need a new node holding things together then. Make // one and promote it to the right type. // TIntermBinary* node = new TIntermBinary(op); if (line == 0) line = right->getLine(); node->setLine(line); node->setLeft(left); node->setRight(right); if (!node->promote(infoSink)) return 0; // // See if we can fold constants. // TIntermTyped* typedReturnNode = 0; TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); if (leftTempConstant && rightTempConstant) { typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink); if (typedReturnNode) return typedReturnNode; } return node; }