Index: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -542,9 +542,11 @@ 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 void addKImmFPOperands(MCInst &Inst, unsigned N) const; @@ -1173,6 +1175,13 @@ 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 @@ return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(getReg()); } -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; - } +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 { + 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,14 +1718,44 @@ 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(); - Negate = true; } if (getLexer().getKind() == AsmToken::Identifier && @@ -1735,9 +1789,6 @@ } 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 @@ 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(*Operands.back()); Op.setModifiers(Mods); Index: llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp +++ llvm/trunk/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp @@ -543,13 +543,34 @@ const MCSubtargetInfo &STI, raw_ostream &O) { unsigned InputModifiers = MI->getOperand(OpNo).getImm(); - if (InputModifiers & SISrcMods::NEG) - O << '-'; + + // 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, Index: llvm/trunk/test/MC/AMDGPU/literals.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/literals.s +++ llvm/trunk/test/MC/AMDGPU/literals.s @@ -248,12 +248,12 @@ // 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] Index: llvm/trunk/test/MC/AMDGPU/vop3-modifiers-err.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/vop3-modifiers-err.s +++ llvm/trunk/test/MC/AMDGPU/vop3-modifiers-err.s @@ -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 \ No newline at end of file Index: llvm/trunk/test/MC/AMDGPU/vop3-modifiers.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/vop3-modifiers.s +++ llvm/trunk/test/MC/AMDGPU/vop3-modifiers.s @@ -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] \ No newline at end of file Index: llvm/trunk/test/MC/AMDGPU/vop3.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/vop3.s +++ llvm/trunk/test/MC/AMDGPU/vop3.s @@ -265,11 +265,11 @@ 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 Index: llvm/trunk/test/MC/Disassembler/AMDGPU/vop3_vi.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/AMDGPU/vop3_vi.txt +++ llvm/trunk/test/MC/Disassembler/AMDGPU/vop3_vi.txt @@ -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