22 switch (this->
kind()) {
50 case Kind::BITWISEANDEQ:
51 case Kind::BITWISEXOREQ:
54 default:
SK_ABORT(
"unsupported binary operator");
59 switch (this->
kind()) {
61 case Kind::MINUS:
return " - ";
62 case Kind::STAR:
return " * ";
63 case Kind::SLASH:
return " / ";
64 case Kind::PERCENT:
return " % ";
65 case Kind::SHL:
return " << ";
66 case Kind::SHR:
return " >> ";
67 case Kind::LOGICALNOT:
return "!";
68 case Kind::LOGICALAND:
return " && ";
69 case Kind::LOGICALOR:
return " || ";
70 case Kind::LOGICALXOR:
return " ^^ ";
71 case Kind::BITWISENOT:
return "~";
72 case Kind::BITWISEAND:
return " & ";
73 case Kind::BITWISEOR:
return " | ";
74 case Kind::BITWISEXOR:
return " ^ ";
76 case Kind::EQEQ:
return " == ";
77 case Kind::NEQ:
return " != ";
80 case Kind::LTEQ:
return " <= ";
81 case Kind::GTEQ:
return " >= ";
82 case Kind::PLUSEQ:
return " += ";
83 case Kind::MINUSEQ:
return " -= ";
84 case Kind::STAREQ:
return " *= ";
85 case Kind::SLASHEQ:
return " /= ";
86 case Kind::PERCENTEQ:
return " %= ";
87 case Kind::SHLEQ:
return " <<= ";
88 case Kind::SHREQ:
return " >>= ";
89 case Kind::BITWISEANDEQ:
return " &= ";
90 case Kind::BITWISEOREQ:
return " |= ";
91 case Kind::BITWISEXOREQ:
return " ^= ";
92 case Kind::PLUSPLUS:
return "++";
93 case Kind::MINUSMINUS:
return "--";
102 name.remove_prefix(1);
105 name.remove_suffix(1);
111 switch (this->
kind()) {
117 case Kind::PERCENTEQ:
120 case Kind::BITWISEOREQ:
121 case Kind::BITWISEXOREQ:
122 case Kind::BITWISEANDEQ:
134 switch (this->
kind()) {
136 case Kind::MINUSEQ:
return Kind::MINUS;
137 case Kind::STAREQ:
return Kind::STAR;
138 case Kind::SLASHEQ:
return Kind::SLASH;
139 case Kind::PERCENTEQ:
return Kind::PERCENT;
140 case Kind::SHLEQ:
return Kind::SHL;
141 case Kind::SHREQ:
return Kind::SHR;
142 case Kind::BITWISEOREQ:
return Kind::BITWISEOR;
143 case Kind::BITWISEXOREQ:
return Kind::BITWISEXOR;
144 case Kind::BITWISEANDEQ:
return Kind::BITWISEAND;
145 default:
return *
this;
150 switch (this->
kind()) {
162 switch (this->
kind()) {
165 case Kind::BITWISEAND:
166 case Kind::BITWISEOR:
167 case Kind::BITWISEXOR:
171 case Kind::BITWISEANDEQ:
172 case Kind::BITWISEOREQ:
173 case Kind::BITWISEXOREQ:
174 case Kind::PERCENTEQ:
182 switch (this->
kind()) {
190 case Kind::BITWISEAND:
191 case Kind::BITWISEOR:
192 case Kind::BITWISEXOR:
197 case Kind::PERCENTEQ:
200 case Kind::BITWISEANDEQ:
201 case Kind::BITWISEOREQ:
202 case Kind::BITWISEXOREQ:
209bool Operator::isMatrixMultiply(
const Type& left,
const Type& right)
const {
210 if (this->
kind() != Kind::STAR && this->
kind() != Kind::STAREQ) {
213 if (left.isMatrix()) {
214 return right.isMatrix() || right.isVector();
216 return left.isVector() &&
right.isMatrix();
226 const Type** outLeftType,
227 const Type** outRightType,
228 const Type** outResultType)
const {
230 switch (this->
kind()) {
235 *outLeftType = &left;
236 *outRightType = &left;
237 *outResultType = &left;
238 return right.canCoerceTo(left, allowNarrowing);
242 if (left.isVoid() || left.isOpaque()) {
246 leftToRight = left.coercionCost(right);
247 if (rightToLeft < leftToRight) {
249 *outLeftType = &left;
250 *outRightType = &left;
255 if (leftToRight.isPossible(allowNarrowing)) {
256 *outLeftType = &right;
257 *outRightType = &right;
264 case Kind::LOGICALOR:
265 case Kind::LOGICALAND:
266 case Kind::LOGICALXOR:
270 return left.canCoerceTo(*context.
fTypes.
fBool, allowNarrowing) &&
271 right.canCoerceTo(*context.
fTypes.
fBool, allowNarrowing);
274 if (left.isOpaque() || right.isOpaque()) {
277 *outLeftType = &left;
278 *outRightType = &right;
279 *outResultType = &right;
288 const Type& leftComponentType = left.componentType();
289 const Type& rightComponentType = right.componentType();
295 if (this->isMatrixMultiply(left, right)) {
298 outLeftType, outRightType, outResultType)) {
302 *outLeftType = &(*outResultType)->
toCompound(context, left.columns(), left.rows());
303 *outRightType = &(*outResultType)->
toCompound(context, right.columns(), right.rows());
304 int leftColumns = left.columns(), leftRows = left.rows();
305 int rightColumns = right.columns(), rightRows = right.rows();
306 if (right.isVector()) {
311 if (rightColumns > 1) {
312 *outResultType = &(*outResultType)->
toCompound(context, rightColumns, leftRows);
315 *outResultType = &(*outResultType)->
toCompound(context, leftRows, rightColumns);
317 if (
isAssignment && ((*outResultType)->columns() != leftColumns ||
318 (*outResultType)->rows() != leftRows)) {
321 return leftColumns == rightRows;
324 bool leftIsVectorOrMatrix = left.isVector() || left.isMatrix();
327 if (leftIsVectorOrMatrix && validMatrixOrVectorOp && right.isScalar()) {
330 outLeftType, outRightType, outResultType)) {
334 *outLeftType = &(*outLeftType)->
toCompound(context, left.columns(), left.rows());
336 *outResultType = &(*outResultType)->
toCompound(context, left.columns(), left.rows());
341 bool rightIsVectorOrMatrix = right.isVector() || right.isMatrix();
343 if (!
isAssignment && rightIsVectorOrMatrix && validMatrixOrVectorOp && left.isScalar()) {
346 outLeftType, outRightType, outResultType)) {
350 *outRightType = &(*outRightType)->
toCompound(context, right.columns(), right.rows());
352 *outResultType = &(*outResultType)->
toCompound(context, right.columns(), right.rows());
357 CoercionCost rightToLeftCost = right.coercionCost(left);
359 : left.coercionCost(right);
361 if ((left.isScalar() && right.isScalar()) || (leftIsVectorOrMatrix && validMatrixOrVectorOp)) {
367 if (rightToLeftCost.
isPossible(allowNarrowing) && rightToLeftCost < leftToRightCost) {
369 *outLeftType = &left;
370 *outRightType = &left;
371 *outResultType = &left;
372 }
else if (leftToRightCost.
isPossible(allowNarrowing)) {
374 *outLeftType = &right;
375 *outRightType = &right;
376 *outResultType = &right;
#define SK_ABORT(message,...)
void swap(sk_sp< T > &a, sk_sp< T > &b)
const std::unique_ptr< Type > fBool
const BuiltinTypes & fTypes
std::string_view tightOperatorName() const
OperatorPrecedence getBinaryPrecedence() const
bool isRelational() const
const char * operatorName() const
Operator removeAssignment() const
bool isCompoundAssignment() const
bool isOnlyValidForIntegralTypes() const
bool determineBinaryType(const Context &context, const Type &left, const Type &right, const Type **outLeftType, const Type **outRightType, const Type **outResultType) const
bool isValidForMatrixOrVector() const
bool isAssignment() const
const Type & toCompound(const Context &context, int columns, int rows) const
DEF_SWITCHES_START aot vmservice shared library name
constexpr bool starts_with(std::string_view str, std::string_view prefix)
constexpr bool ends_with(std::string_view str, std::string_view suffix)
static CoercionCost Impossible()
bool isPossible(bool allowNarrowing) const
ProgramSettings fSettings
bool fAllowNarrowingConversions