forked from OSchip/llvm-project
[AMDGPU][MC] Fix for Bugs 28200, 28202 + LIT tests
Fixed several related issues with VOP3 fp modifiers. Reviewers: artem.tamazov Differential Revision: https://reviews.llvm.org/D30821 llvm-svn: 298255
This commit is contained in:
parent
d79253a9f7
commit
40af9c35d3
|
@ -542,9 +542,11 @@ public:
|
|||
return getModifiers().hasIntModifiers();
|
||||
}
|
||||
|
||||
uint64_t applyInputFPModifiers(uint64_t Val, unsigned Size) const;
|
||||
|
||||
void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const;
|
||||
|
||||
void addLiteralImmOperand(MCInst &Inst, int64_t Val) const;
|
||||
void addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyModifiers) const;
|
||||
|
||||
template <unsigned Bitwidth>
|
||||
void addKImmFPOperands(MCInst &Inst, unsigned N) const;
|
||||
|
@ -1173,6 +1175,13 @@ bool AMDGPUOperand::isLiteralImm(MVT type) const {
|
|||
if (!Imm.IsFPImm) {
|
||||
// We got int literal token.
|
||||
|
||||
if (type == MVT::f64 && hasFPModifiers()) {
|
||||
// Cannot apply fp modifiers to int literals preserving the same semantics
|
||||
// for VOP1/2/C and VOP3 because of integer truncation. To avoid ambiguity,
|
||||
// disable these cases.
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned Size = type.getSizeInBits();
|
||||
if (Size == 64)
|
||||
Size = 32;
|
||||
|
@ -1202,33 +1211,48 @@ bool AMDGPUOperand::isRegClass(unsigned RCID) const {
|
|||
return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(getReg());
|
||||
}
|
||||
|
||||
uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val, unsigned Size) const
|
||||
{
|
||||
assert(isImmTy(ImmTyNone) && Imm.Mods.hasFPModifiers());
|
||||
assert(Size == 2 || Size == 4 || Size == 8);
|
||||
|
||||
const uint64_t FpSignMask = (1ULL << (Size * 8 - 1));
|
||||
|
||||
if (Imm.Mods.Abs) {
|
||||
Val &= ~FpSignMask;
|
||||
}
|
||||
if (Imm.Mods.Neg) {
|
||||
Val ^= FpSignMask;
|
||||
}
|
||||
|
||||
return Val;
|
||||
}
|
||||
|
||||
void AMDGPUOperand::addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers) const {
|
||||
int64_t Val = Imm.Val;
|
||||
if (isImmTy(ImmTyNone) && ApplyModifiers && Imm.Mods.hasFPModifiers() && Imm.Mods.Neg) {
|
||||
// Apply modifiers to immediate value. Only negate can get here
|
||||
if (Imm.IsFPImm) {
|
||||
APFloat F(BitsToDouble(Val));
|
||||
F.changeSign();
|
||||
Val = F.bitcastToAPInt().getZExtValue();
|
||||
} else {
|
||||
Val = -Val;
|
||||
}
|
||||
}
|
||||
|
||||
if (AMDGPU::isSISrcOperand(AsmParser->getMII()->get(Inst.getOpcode()),
|
||||
Inst.getNumOperands())) {
|
||||
addLiteralImmOperand(Inst, Val);
|
||||
addLiteralImmOperand(Inst, Imm.Val,
|
||||
ApplyModifiers &
|
||||
isImmTy(ImmTyNone) && Imm.Mods.hasFPModifiers());
|
||||
} else {
|
||||
Inst.addOperand(MCOperand::createImm(Val));
|
||||
assert(!isImmTy(ImmTyNone) || !hasModifiers());
|
||||
Inst.addOperand(MCOperand::createImm(Imm.Val));
|
||||
}
|
||||
}
|
||||
|
||||
void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val) const {
|
||||
void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyModifiers) const {
|
||||
const auto& InstDesc = AsmParser->getMII()->get(Inst.getOpcode());
|
||||
auto OpNum = Inst.getNumOperands();
|
||||
// Check that this operand accepts literals
|
||||
assert(AMDGPU::isSISrcOperand(InstDesc, OpNum));
|
||||
|
||||
if (ApplyModifiers) {
|
||||
assert(AMDGPU::isSISrcFPOperand(InstDesc, OpNum));
|
||||
const unsigned Size = Imm.IsFPImm ? sizeof(double) : getOperandSize(InstDesc, OpNum);
|
||||
Val = applyInputFPModifiers(Val, Size);
|
||||
}
|
||||
|
||||
APInt Literal(64, Val);
|
||||
uint8_t OpTy = InstDesc.OpInfo[OpNum].OperandType;
|
||||
|
||||
|
@ -1694,15 +1718,45 @@ AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands) {
|
|||
OperandMatchResultTy
|
||||
AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
|
||||
bool AllowImm) {
|
||||
// XXX: During parsing we can't determine if minus sign means
|
||||
// negate-modifier or negative immediate value.
|
||||
// By default we suppose it is modifier.
|
||||
bool Negate = false, Abs = false, Abs2 = false;
|
||||
bool Negate = false, Negate2 = false, Abs = false, Abs2 = false;
|
||||
|
||||
if (getLexer().getKind()== AsmToken::Minus) {
|
||||
const AsmToken NextToken = getLexer().peekTok();
|
||||
|
||||
// Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
|
||||
if (NextToken.is(AsmToken::Minus)) {
|
||||
Error(Parser.getTok().getLoc(), "invalid syntax, expected 'neg' modifier");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
// '-' followed by an integer literal N should be interpreted as integer
|
||||
// negation rather than a floating-point NEG modifier applied to N.
|
||||
// Beside being contr-intuitive, such use of floating-point NEG modifier
|
||||
// results in different meaning of integer literals used with VOP1/2/C
|
||||
// and VOP3, for example:
|
||||
// v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
|
||||
// v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
|
||||
// Negative fp literals should be handled likewise for unifomtity
|
||||
if (!NextToken.is(AsmToken::Integer) && !NextToken.is(AsmToken::Real)) {
|
||||
Parser.Lex();
|
||||
Negate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (getLexer().getKind() == AsmToken::Identifier &&
|
||||
Parser.getTok().getString() == "neg") {
|
||||
if (Negate) {
|
||||
Error(Parser.getTok().getLoc(), "expected register or immediate");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex();
|
||||
Negate2 = true;
|
||||
if (getLexer().isNot(AsmToken::LParen)) {
|
||||
Error(Parser.getTok().getLoc(), "expected left paren after neg");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex();
|
||||
}
|
||||
|
||||
if (getLexer().getKind() == AsmToken::Identifier &&
|
||||
Parser.getTok().getString() == "abs") {
|
||||
|
@ -1735,9 +1789,6 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
|
|||
}
|
||||
|
||||
AMDGPUOperand::Modifiers Mods;
|
||||
if (Negate) {
|
||||
Mods.Neg = true;
|
||||
}
|
||||
if (Abs) {
|
||||
if (getLexer().getKind() != AsmToken::Pipe) {
|
||||
Error(Parser.getTok().getLoc(), "expected vertical bar");
|
||||
|
@ -1755,6 +1806,17 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
|
|||
Mods.Abs = true;
|
||||
}
|
||||
|
||||
if (Negate) {
|
||||
Mods.Neg = true;
|
||||
} else if (Negate2) {
|
||||
if (getLexer().isNot(AsmToken::RParen)) {
|
||||
Error(Parser.getTok().getLoc(), "expected closing parentheses");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex();
|
||||
Mods.Neg = true;
|
||||
}
|
||||
|
||||
if (Mods.hasFPModifiers()) {
|
||||
AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
|
||||
Op.setModifiers(Mods);
|
||||
|
|
|
@ -543,13 +543,34 @@ void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
|
|||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
unsigned InputModifiers = MI->getOperand(OpNo).getImm();
|
||||
if (InputModifiers & SISrcMods::NEG)
|
||||
|
||||
// Use 'neg(...)' instead of '-' to avoid ambiguity.
|
||||
// This is important for integer literals because
|
||||
// -1 is not the same value as neg(1).
|
||||
bool NegMnemo = false;
|
||||
|
||||
if (InputModifiers & SISrcMods::NEG) {
|
||||
if (OpNo + 1 < MI->getNumOperands() &&
|
||||
(InputModifiers & SISrcMods::ABS) == 0) {
|
||||
const MCOperand &Op = MI->getOperand(OpNo + 1);
|
||||
NegMnemo = Op.isImm() || Op.isFPImm();
|
||||
}
|
||||
if (NegMnemo) {
|
||||
O << "neg(";
|
||||
} else {
|
||||
O << '-';
|
||||
}
|
||||
}
|
||||
|
||||
if (InputModifiers & SISrcMods::ABS)
|
||||
O << '|';
|
||||
printOperand(MI, OpNo + 1, STI, O);
|
||||
if (InputModifiers & SISrcMods::ABS)
|
||||
O << '|';
|
||||
|
||||
if (NegMnemo) {
|
||||
O << ')';
|
||||
}
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
|
||||
|
|
|
@ -248,12 +248,12 @@ v_trunc_f32_e32 v0, -13
|
|||
// VI: v_fract_f64_e32 v[0:1], -13 ; encoding: [0xcd,0x64,0x00,0x7e]
|
||||
v_fract_f64_e32 v[0:1], -13
|
||||
|
||||
// SICI: v_trunc_f32_e64 v0, -13 ; encoding: [0x00,0x00,0x42,0xd3,0x8d,0x00,0x00,0x20]
|
||||
// VI: v_trunc_f32_e64 v0, -13 ; encoding: [0x00,0x00,0x5c,0xd1,0x8d,0x00,0x00,0x20]
|
||||
// SICI: v_trunc_f32_e64 v0, -13 ; encoding: [0x00,0x00,0x42,0xd3,0xcd,0x00,0x00,0x00]
|
||||
// VI: v_trunc_f32_e64 v0, -13 ; encoding: [0x00,0x00,0x5c,0xd1,0xcd,0x00,0x00,0x00]
|
||||
v_trunc_f32_e64 v0, -13
|
||||
|
||||
// SICI: v_fract_f64_e64 v[0:1], -13 ; encoding: [0x00,0x00,0x7c,0xd3,0x8d,0x00,0x00,0x20]
|
||||
// VI: v_fract_f64_e64 v[0:1], -13 ; encoding: [0x00,0x00,0x72,0xd1,0x8d,0x00,0x00,0x20]
|
||||
// SICI: v_fract_f64_e64 v[0:1], -13 ; encoding: [0x00,0x00,0x7c,0xd3,0xcd,0x00,0x00,0x00]
|
||||
// VI: v_fract_f64_e64 v[0:1], -13 ; encoding: [0x00,0x00,0x72,0xd1,0xcd,0x00,0x00,0x00]
|
||||
v_fract_f64_e64 v[0:1], -13
|
||||
|
||||
// SICI: v_trunc_f32_e32 v0, 35 ; encoding: [0xa3,0x42,0x00,0x7e]
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck %s
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
// VOP3 Modifiers
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
// 'neg(1)' cannot be encoded as 32-bit literal while preserving e64 semantics
|
||||
v_ceil_f64_e32 v[0:1], neg(1)
|
||||
// CHECK: error: invalid operand for instruction
|
||||
|
||||
v_ceil_f32 v0, --1
|
||||
// CHECK: error: invalid syntax, expected 'neg' modifier
|
||||
|
||||
v_ceil_f16 v0, abs(neg(1))
|
||||
// CHECK: error: not a valid operand
|
|
@ -0,0 +1,258 @@
|
|||
// RUN: llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck %s
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
// VOP1/VOP3 F16
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
v_ceil_f16 v0, -1
|
||||
// CHECK: [0xc1,0x8a,0x00,0x7e]
|
||||
|
||||
v_ceil_f16 v0, -2
|
||||
// CHECK: [0xc2,0x8a,0x00,0x7e]
|
||||
|
||||
v_ceil_f16 v0, -16
|
||||
// CHECK: [0xd0,0x8a,0x00,0x7e]
|
||||
|
||||
v_ceil_f16 v0, -0.5
|
||||
// CHECK: [0xf1,0x8a,0x00,0x7e]
|
||||
|
||||
v_ceil_f16 v0, -1.0
|
||||
// CHECK: [0xf3,0x8a,0x00,0x7e]
|
||||
|
||||
v_ceil_f16 v0, -2.0
|
||||
// CHECK: [0xf5,0x8a,0x00,0x7e]
|
||||
|
||||
v_ceil_f16 v0, -4.0
|
||||
// CHECK: [0xf7,0x8a,0x00,0x7e]
|
||||
|
||||
// Arbitrary f16 literal in hex
|
||||
v_ceil_f16 v0, 0xabcd
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0xcd,0xab,0x00,0x00]
|
||||
|
||||
// '-' is a part of hex literal (not a 'neg' modifier)
|
||||
v_ceil_f16 v0, -0x5433
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0xcd,0xab,0x00,0x00]
|
||||
|
||||
v_ceil_f16 v0, abs(0xabcd)
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0xcd,0x2b,0x00,0x00]
|
||||
|
||||
v_ceil_f16 v0, neg(0xabcd)
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0xcd,0x2b,0x00,0x00]
|
||||
|
||||
v_ceil_f16 v0, neg(abs(0xabcd))
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0xcd,0xab,0x00,0x00]
|
||||
|
||||
v_ceil_f16 v0, -abs(0xabcd)
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0xcd,0xab,0x00,0x00]
|
||||
|
||||
// 1/(2*pi) encoded as inline constant in VOP1
|
||||
v_ceil_f16 v0, 0x3118
|
||||
// CHECK: [0xf8,0x8a,0x00,0x7e]
|
||||
|
||||
// 1/(2*pi) encoded as inline constant in VOP3
|
||||
v_ceil_f16_e64 v0, 0x3118
|
||||
// CHECK: [0x00,0x00,0x85,0xd1,0xf8,0x00,0x00,0x00]
|
||||
|
||||
// neg(-1/(2*pi)) = 1/(2*pi)
|
||||
v_ceil_f16 v0, neg(0xb118)
|
||||
// CHECK: [0xf8,0x8a,0x00,0x7e]
|
||||
|
||||
// -1/(2*pi) cannot be encoded as inline constant in VOP1
|
||||
v_ceil_f16 v0, 0xb118
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0x18,0xb1,0x00,0x00]
|
||||
|
||||
// -1/(2*pi) cannot be encoded as inline constant in VOP1
|
||||
v_ceil_f16 v0, neg(0x3118)
|
||||
// CHECK: [0xff,0x8a,0x00,0x7e,0x18,0xb1,0x00,0x00]
|
||||
|
||||
// -1/(2*pi) can be encoded as inline constant w/ modifiers in VOP3
|
||||
v_ceil_f16_e64 v0, neg(0x3118)
|
||||
// CHECK: [0x00,0x00,0x85,0xd1,0xf8,0x00,0x00,0x20]
|
||||
|
||||
v_ceil_f16_e64 v0, abs(0x3118)
|
||||
// CHECK: 0x00,0x01,0x85,0xd1,0xf8,0x00,0x00,0x00]
|
||||
|
||||
v_ceil_f16_e64 v0, neg(abs(0x3118))
|
||||
// CHECK: [0x00,0x01,0x85,0xd1,0xf8,0x00,0x00,0x20]
|
||||
|
||||
v_ceil_f16_e64 v0, neg(|v1|)
|
||||
// CHECK: [0x00,0x01,0x85,0xd1,0x01,0x01,0x00,0x20]
|
||||
|
||||
v_ceil_f16_e64 v0, -|v1|
|
||||
// CHECK: [0x00,0x01,0x85,0xd1,0x01,0x01,0x00,0x20]
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
// VOP1/VOP3 F64
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
// Encoded as inline constant 1 with 'neg' modifier
|
||||
v_ceil_f64 v[0:1], neg(1)
|
||||
// CHECK: [0x00,0x00,0x58,0xd1,0x81,0x00,0x00,0x20]
|
||||
|
||||
// Encoded as inline constant -1 with 'neg' modifier
|
||||
v_ceil_f64 v[0:1], neg(-1)
|
||||
// CHECK: [0x00,0x00,0x58,0xd1,0xc1,0x00,0x00,0x20]
|
||||
|
||||
v_ceil_f64_e32 v[0:1], 1.0
|
||||
// CHECK: [0xf2,0x30,0x00,0x7e]
|
||||
|
||||
// abs(1.0) = 1.0
|
||||
v_ceil_f64_e32 v[0:1], abs(1.0)
|
||||
// CHECK: [0xf2,0x30,0x00,0x7e]
|
||||
|
||||
// neg(1.0) = -1.0
|
||||
v_ceil_f64_e32 v[0:1], neg(1.0)
|
||||
// CHECK: [0xf3,0x30,0x00,0x7e]
|
||||
|
||||
// 1/(2*pi) encoded as inline constant in VOP1
|
||||
v_ceil_f64 v[0:1], 0x3fc45f306dc9c882
|
||||
// CHECK: [0xf8,0x30,0x00,0x7e]
|
||||
|
||||
// 1/(2*pi) encoded as inline constant in VOP3
|
||||
v_ceil_f64_e64 v[0:1], 0x3fc45f306dc9c882
|
||||
// CHECK: [0x00,0x00,0x58,0xd1,0xf8,0x00,0x00,0x00]
|
||||
|
||||
// -1/(2*pi) cannot be encoded as inline constant in VOP1.
|
||||
// It cannot be encoded as literal either due to int literal rules.
|
||||
// So it is encoded as VOP3
|
||||
v_ceil_f64 v[0:1], abs(0x3fc45f306dc9c882)
|
||||
// CHECK: [0x00,0x01,0x58,0xd1,0xf8,0x00,0x00,0x00]
|
||||
|
||||
v_ceil_f64 v[0:1], neg(abs(0x3fc45f306dc9c882))
|
||||
// CHECK: [0x00,0x01,0x58,0xd1,0xf8,0x00,0x00,0x20]
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
// VOP2/VOP3 F32
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
v_add_f32 v5, -1, v2
|
||||
// CHECK: [0xc1,0x04,0x0a,0x02]
|
||||
|
||||
v_add_f32 v5, -16, v2
|
||||
// CHECK: [0xd0,0x04,0x0a,0x02]
|
||||
|
||||
v_add_f32 v5, 0x3e22f983, v2
|
||||
// CHECK: [0xf8,0x04,0x0a,0x02]
|
||||
|
||||
// abs(1/(2*pi)) = 1/(2*pi)
|
||||
v_add_f32 v5, abs(0x3e22f983), v2
|
||||
// CHECK: [0xf8,0x04,0x0a,0x02]
|
||||
|
||||
// neg(-1/(2*pi)) = 1/(2*pi)
|
||||
v_add_f32 v5, neg(0xbe22f983), v2
|
||||
// CHECK: [0xf8,0x04,0x0a,0x02]
|
||||
|
||||
// -1/(2*pi) cannot be encoded as inline constant in VOP1
|
||||
v_add_f32 v5, neg(0x3e22f983), v2
|
||||
// CHECK: [0xff,0x04,0x0a,0x02,0x83,0xf9,0x22,0xbe]
|
||||
|
||||
|
||||
v_add_f32_e64 v0, -2, s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xc2,0x00,0x00,0x00]
|
||||
|
||||
v_add_f32_e64 v0, -16, s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xd0,0x00,0x00,0x00]
|
||||
|
||||
v_add_f32_e64 v0, -0.5, s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xf1,0x00,0x00,0x00]
|
||||
|
||||
v_add_f32_e64 v0, -1.0, s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xf3,0x00,0x00,0x00]
|
||||
|
||||
v_add_f32_e64 v0, -2.0, s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xf5,0x00,0x00,0x00]
|
||||
|
||||
v_add_f32_e64 v0, -4.0, s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xf7,0x00,0x00,0x00]
|
||||
|
||||
v_add_f32_e64 v0, 0x3e22f983, s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xf8,0x00,0x00,0x00]
|
||||
|
||||
v_add_f32_e64 v0, neg(0x3e22f983), s0
|
||||
// CHECK: [0x00,0x00,0x01,0xd1,0xf8,0x00,0x00,0x20]
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
// VOPC/VOP3
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
v_cmp_eq_f16 vcc, -1, v0
|
||||
// CHECK: [0xc1,0x00,0x44,0x7c]
|
||||
|
||||
v_cmp_eq_f16_e64 s[0:1], s0, -1
|
||||
// CHECK: [0x00,0x00,0x22,0xd0,0x00,0x82,0x01,0x00]
|
||||
|
||||
v_cmp_eq_f16_e64 s[0:1], s0, 0x3118
|
||||
// CHECK: [0x00,0x00,0x22,0xd0,0x00,0xf0,0x01,0x00]
|
||||
|
||||
v_cmp_eq_f16_e64 s[0:1], s0, neg(0x3118)
|
||||
// CHECK: [0x00,0x00,0x22,0xd0,0x00,0xf0,0x01,0x40]
|
||||
|
||||
v_cmp_eq_f32 vcc, -4.0, v0
|
||||
// CHECK: [0xf7,0x00,0x84,0x7c]
|
||||
|
||||
// 1/(2*pi) can be encoded as inline constant
|
||||
v_cmp_eq_f32 vcc, 0x3e22f983, v0
|
||||
// CHECK: [0xf8,0x00,0x84,0x7c]
|
||||
|
||||
// -1/(2*pi) cannot be encoded as inline constant in VOPC
|
||||
v_cmp_eq_f32 vcc, neg(0x3e22f983), v0
|
||||
// CHECK: [0xff,0x00,0x84,0x7c,0x83,0xf9,0x22,0xbe]
|
||||
|
||||
// abs(1/(2*pi)) = 1/(2*pi)
|
||||
v_cmp_eq_f32 vcc, abs(0x3e22f983), v0
|
||||
// CHECK: [0xf8,0x00,0x84,0x7c]
|
||||
|
||||
// -1/(2*pi) can be encoded as inline constant w/ modifiers in VOP3
|
||||
v_cmp_eq_f32_e64 vcc, neg(0x3e22f983), v0
|
||||
// CHECK: [0x6a,0x00,0x42,0xd0,0xf8,0x00,0x02,0x20]
|
||||
|
||||
v_cmp_eq_f32_e64 vcc, v0, abs(0x3e22f983)
|
||||
// CHECK: [0x6a,0x02,0x42,0xd0,0x00,0xf1,0x01,0x00]
|
||||
|
||||
v_cmp_eq_f32_e64 vcc, v0, -abs(0x3e22f983)
|
||||
// CHECK: [0x6a,0x02,0x42,0xd0,0x00,0xf1,0x01,0x40]
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
// VOP3
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
v_add_f64 v[0:1], s[0:1], -1
|
||||
// CHECK: [0x00,0x00,0x80,0xd2,0x00,0x82,0x01,0x00]
|
||||
|
||||
v_add_f64 v[0:1], s[0:1], -16
|
||||
// CHECK: [0x00,0x00,0x80,0xd2,0x00,0xa0,0x01,0x00]
|
||||
|
||||
v_add_f64 v[0:1], s[0:1], -0.5
|
||||
// CHECK: [0x00,0x00,0x80,0xd2,0x00,0xe2,0x01,0x00]
|
||||
|
||||
v_add_f64 v[0:1], s[0:1], -1.0
|
||||
// CHECK: [0x00,0x00,0x80,0xd2,0x00,0xe6,0x01,0x00]
|
||||
|
||||
v_add_f64 v[0:1], s[0:1], -2.0
|
||||
// CHECK: [0x00,0x00,0x80,0xd2,0x00,0xea,0x01,0x00]
|
||||
|
||||
v_add_f64 v[0:1], s[0:1], -4.0
|
||||
// CHECK: [0x00,0x00,0x80,0xd2,0x00,0xee,0x01,0x00]
|
||||
|
||||
v_add_f64 v[4:5], s[0:1], 0x3fc45f306dc9c882
|
||||
// CHECK: [0x04,0x00,0x80,0xd2,0x00,0xf0,0x01,0x00]
|
||||
|
||||
v_add_f64 v[4:5], s[0:1], neg(0x3fc45f306dc9c882)
|
||||
// CHECK: [0x04,0x00,0x80,0xd2,0x00,0xf0,0x01,0x40]
|
||||
|
||||
|
||||
v_cubeid_f32 v0, s0, s0, -1
|
||||
// CHECK: [0x00,0x00,0xc4,0xd1,0x00,0x00,0x04,0x03]
|
||||
|
||||
v_cubeid_f32 v0, s0, s0, -4.0
|
||||
// CHECK: [0x00,0x00,0xc4,0xd1,0x00,0x00,0xdc,0x03]
|
||||
|
||||
v_cubeid_f32 v0, s0, s0, 0x3e22f983
|
||||
// CHECK: [0x00,0x00,0xc4,0xd1,0x00,0x00,0xe0,0x03]
|
||||
|
||||
v_cubeid_f32 v0, s0, s0, neg(0x3e22f983)
|
||||
// CHECK: [0x00,0x00,0xc4,0xd1,0x00,0x00,0xe0,0x83]
|
||||
|
||||
v_cubeid_f32 v0, s0, s0, abs(0x3e22f983)
|
||||
// CHECK: [0x00,0x04,0xc4,0xd1,0x00,0x00,0xe0,0x03]
|
|
@ -265,11 +265,11 @@ v_mac_f16_e64 v0, 0.5, flat_scratch_lo
|
|||
|
||||
v_mac_f16_e64 v0, -4.0, flat_scratch_lo
|
||||
// NOSICI: error:
|
||||
// VI: v_mac_f16_e64 v0, -4.0, flat_scratch_lo ; encoding: [0x00,0x00,0x23,0xd1,0xf6,0xcc,0x00,0x20]
|
||||
// VI: v_mac_f16_e64 v0, -4.0, flat_scratch_lo ; encoding: [0x00,0x00,0x23,0xd1,0xf7,0xcc,0x00,0x00]
|
||||
|
||||
v_mac_f16_e64 v0, flat_scratch_lo, -4.0
|
||||
// NOSICI: error:
|
||||
// VI: v_mac_f16_e64 v0, flat_scratch_lo, -4.0 ; encoding: [0x00,0x00,0x23,0xd1,0x66,0xec,0x01,0x40]
|
||||
// VI: v_mac_f16_e64 v0, flat_scratch_lo, -4.0 ; encoding: [0x00,0x00,0x23,0xd1,0x66,0xee,0x01,0x00]
|
||||
|
||||
///===---------------------------------------------------------------------===//
|
||||
// VOP3 Instructions
|
||||
|
|
|
@ -215,3 +215,9 @@
|
|||
|
||||
# VI: v_mad_f32 v9, 0.5, v5, -v8 ; encoding: [0x09,0x00,0xc1,0xd1,0xf0,0x0a,0x22,0x84]
|
||||
0x09 0x00 0xc1 0xd1 0xf0 0x0a 0x22 0x84
|
||||
|
||||
# VI: v_ceil_f32_e64 v0, neg(-1) ; encoding: [0x00,0x00,0x5d,0xd1,0xc1,0x00,0x00,0x20]
|
||||
0x00,0x00,0x5d,0xd1,0xc1,0x00,0x00,0x20
|
||||
|
||||
# VI: v_ceil_f32_e64 v0, neg(-1.0) ; encoding: [0x00,0x00,0x5d,0xd1,0xf3,0x00,0x00,0x20]
|
||||
0x00,0x00,0x5d,0xd1,0xf3,0x00,0x00,0x20
|
||||
|
|
Loading…
Reference in New Issue