}
}
+ /* Value if this were used with vop3/opsel or vop3p. */
+ constexpr uint16_t constantValue16(bool opsel) const noexcept
+ {
+ assert(bytes() == 2 || bytes() == 4);
+ if (opsel) {
+ if (bytes() == 2 && int16_t(data_.i) >= -16 && int16_t(data_.i) <= 64 && !isLiteral())
+ return int16_t(data_.i) >> 16; /* 16-bit inline integers are sign-extended, even with fp16 instrs */
+ else
+ return data_.i >> 16;
+ }
+ return data_.i;
+ }
+
constexpr bool isOfType(RegType type) const noexcept
{
return hasRegClass() && regClass().type() == type;
val = constant;
/* check that no upper bits are lost in case of packed 16bit constants */
- if (gfx_level >= GFX8 && !op16.isLiteral() && op16.constantValue64() == constant)
+ if (gfx_level >= GFX8 && !op16.isLiteral() &&
+ op16.constantValue16(true) == ((constant >> 16) & 0xffff))
add_label(label_constant_16bit);
if (!op32.isLiteral())
uint32_t const0 = 0, const1 = 0;
for (int i = 0; i < 3; i++) {
uint32_t val;
+ bool hi16 = opsel & (1 << i);
if (operands[i].isConstant()) {
- val = operands[i].constantValue();
+ val = hi16 ? operands[i].constantValue16(true) : operands[i].constantValue();
} else if (operands[i].isTemp() &&
ctx.info[operands[i].tempId()].is_constant_or_literal(32)) {
- val = ctx.info[operands[i].tempId()].val;
+ val = ctx.info[operands[i].tempId()].val >> (hi16 ? 16 : 0);
} else {
continue;
}
if (const0_idx < 0 || const1_idx < 0)
continue;
- if (opsel & (1 << const0_idx))
- const0 >>= 16;
- if (opsel & (1 << const1_idx))
- const1 >>= 16;
-
int lower_idx = const0_idx;
switch (min) {
case aco_opcode::v_min_f32: