This correction is intended to fix several related issues with VOP3 fp modifiers:
- negative integer literals like '-1' currently have different semantics for VOP1/2/C and VOP3:
- VOP1/2/C: '-1' is encoded as inline constant '-1' (0xFFFFFFFF);
- VOP3: '-1' is encoded as inline constant '1' with fp 'neg' modifier (0x80000001).
- VOP3 fp modifiers are allowed with VOP1/2/C literals and applied to these literals before encoding. However semantics of these modifiers depend on literal type. For example, v_ceil_f16_e32 v0, -abs(1) is encoded with integer inline constant '-1' despite the fact that syntax assumes fp negate.
- syntax like '--1' is considered valid and also has different meaning for VOP1/2/C and VOP3.
- literals with 'abs' modifier are accepted by VOP1/2/C but silently ignored. For example, v_ceil_f16 v0, abs(-1.0) result in the same code as v_ceil_f16 v0, -1.0
- disassembled code may be ambiguous in cases like this: v_ceil_f16 v0, -1 because '-' may be interpreted as either integer negation (i.e. part of an integer literal) or fp negation (i.e. 'neg' modifier)
Here is a summary of changes proposed for fixing these issues:
- '-' before a literal is always interpreted as a part of the literal, not a 'neg' modifier. This way negative literals have the same semantics regardless of context.
- added 'neg(...)' syntax to enforce fp negate semantics when necessary.
- syntax "--N" is disabled. "neg(-N)" should be used instead.
- corrected code that applies VOP3 modifiers to VOP1/2/C literals. These modifiers are always applied with fp semantics regardless of literal type.
- 64-bit integer literals are not allowed with fp modifiers. It is not possible to implement any meaningful way to apply fp modifiers in these cases because 64-bit int and fp literals have different truncation rules.
- corrected asm printer to use 'neg(...)' syntax instead of '-' in cases which otherwise would be ambiguous.