static uint32_t scalarArithmeticOp(ArithmeticOp operation, uint32_t value1, uint32_t value2) { switch (operation) { case OP_OR: return value1 | value2; case OP_AND: return value1 & value2; case OP_XOR: return value1 ^ value2; case OP_ADD_I: return value1 + value2; case OP_SUB_I: return value1 - value2; case OP_MULL_I: return value1 * value2; case OP_MULH_U: return ((uint64_t)value1 * (uint64_t)value2) >> 32; case OP_ASHR: return ((int32_t)value1) >> (value2 & 31); case OP_SHR: return value1 >> (value2 & 31); case OP_SHL: return value1 << (value2 & 31); case OP_CLZ: return value2 == 0 ? 32 : __builtin_clz(value2); case OP_CTZ: return value2 == 0 ? 32 : __builtin_ctz(value2); case OP_MOVE: return value2; case OP_CMPEQ_I: return value1 == value2; case OP_CMPNE_I: return value1 != value2; case OP_CMPGT_I: return (int32_t) value1 > (int32_t) value2; case OP_CMPGE_I: return (int32_t) value1 >= (int32_t) value2; case OP_CMPLT_I: return (int32_t) value1 < (int32_t) value2; case OP_CMPLE_I: return (int32_t) value1 <= (int32_t) value2; case OP_CMPGT_U: return value1 > value2; case OP_CMPGE_U: return value1 >= value2; case OP_CMPLT_U: return value1 < value2; case OP_CMPLE_U: return value1 <= value2; case OP_FTOI: return (int32_t) valueAsFloat(value2); case OP_RECIPROCAL: { // Reciprocal only has 6 bits of accuracy uint32_t result = valueAsInt(1.0 / valueAsFloat(value2 & 0xfffe0000)); if (!isnan(valueAsFloat(result))) result &= 0xfffe0000; // Truncate, but only if not NaN return result; } case OP_SEXT8: return (int32_t)(int8_t) value2; case OP_SEXT16: return (int32_t)(int16_t) value2; case OP_MULH_I: return ((int64_t)(int32_t) value1 * (int64_t)(int32_t) value2) >> 32; case OP_ADD_F: return valueAsInt(valueAsFloat(value1) + valueAsFloat(value2)); case OP_SUB_F: return valueAsInt(valueAsFloat(value1) - valueAsFloat(value2)); case OP_MUL_F: return valueAsInt(valueAsFloat(value1) * valueAsFloat(value2)); case OP_ITOF: return valueAsInt((float)((int32_t)value2)); // itof case OP_CMPGT_F: return valueAsFloat(value1) > valueAsFloat(value2); case OP_CMPGE_F: return valueAsFloat(value1) >= valueAsFloat(value2); case OP_CMPLT_F: return valueAsFloat(value1) < valueAsFloat(value2); case OP_CMPLE_F: return valueAsFloat(value1) <= valueAsFloat(value2); case OP_CMPEQ_F: return valueAsFloat(value1) == valueAsFloat(value2); case OP_CMPNE_F: return valueAsFloat(value1) != valueAsFloat(value2); default: return 0; } }
int ScXmlStreamAttributes::valueAsInt (const QString& attrName, int min, int max, int def) const { int value = valueAsInt(attrName, def); return qMin(max, qMax(value, min)); }