Index: lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -183,11 +183,9 @@ // TODO: We should avoid using host float here. It would be better to // check the float bit values which is what a few other places do. // We've had bot failures before due to weird NaN support on mips hosts. - const float F = BitsToFloat(Imm.Val); - // TODO: Add 1/(2*pi) for VI - return (Imm.Val <= 64 && Imm.Val >= -16) || - (F == 0.0 || F == 0.5 || F == -0.5 || F == 1.0 || F == -1.0 || - F == 2.0 || F == -2.0 || F == 4.0 || F == -4.0); + // FIXME: We can't execute this check here because we don't have info about + // expected operand type + return true; } bool isRegKind() const { @@ -369,22 +367,23 @@ } void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const { - if (isImmTy(ImmTyNone) && ApplyModifiers && Imm.Mods.hasFPModifiers()) { - // Apply modifiers to immediate value - int64_t Val = Imm.Val; - bool Negate = Imm.Mods.Neg; // Only negate can get here + int64_t Val = Imm.Val; + if (isImmTy(ImmTyNone)) { if (Imm.IsFPImm) { - APFloat F(BitsToFloat(Val)); - if (Negate) { + APFloat F(BitsToDouble(Val)); + // Apply modifiers to immediate value. Only negate can get here + if (ApplyModifiers && Imm.Mods.hasFPModifiers() && Imm.Mods.Neg) { F.changeSign(); } - Val = F.bitcastToAPInt().getZExtValue(); + Inst.addOperand(MCOperand::createFPImm(F.convertToDouble())); } else { - Val = Negate ? -Val : Val; + if (ApplyModifiers && Imm.Mods.hasFPModifiers() && Imm.Mods.Neg) { + Val = -Val; + } + Inst.addOperand(MCOperand::createImm(Val)); } - Inst.addOperand(MCOperand::createImm(Val)); } else { - Inst.addOperand(MCOperand::createImm(getImm())); + Inst.addOperand(MCOperand::createImm(Val)); } } @@ -629,6 +628,10 @@ return static_cast(TS); } + const MCRegisterInfo* getRegisterInfo() { + return getContext().getRegisterInfo(); + } + void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; } void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; } void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; } @@ -652,6 +655,7 @@ StringRef parseMnemonicSuffix(StringRef Name); bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) override; + bool ProcessInstruction(MCInst &Inst); OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int); OperandMatchResultTy parseIntWithPrefix(const char *Prefix, @@ -966,6 +970,7 @@ AMDGPUAsmParser::OperandMatchResultTy AMDGPUAsmParser::parseImm(OperandVector &Operands) { + // TODO: add syntactic sugar for 1/(2*PI) bool Minus = false; if (getLexer().getKind() == AsmToken::Minus) { Minus = true; @@ -978,24 +983,19 @@ int64_t IntVal; if (getParser().parseAbsoluteExpression(IntVal)) return MatchOperand_ParseFail; - if (!isInt<32>(IntVal) && !isUInt<32>(IntVal)) { - Error(S, "invalid immediate: only 32-bit values are legal"); - return MatchOperand_ParseFail; - } - if (Minus) IntVal *= -1; Operands.push_back(AMDGPUOperand::CreateImm(IntVal, S)); return MatchOperand_Success; } case AsmToken::Real: { - // FIXME: We should emit an error if a double precisions floating-point - // value is used. I'm not sure the best way to detect this. + // Always parse fp operands as doubles. Convert them to floats and ints + // later in ProcessInstruction() int64_t IntVal; if (getParser().parseAbsoluteExpression(IntVal)) return MatchOperand_ParseFail; - APFloat F((float)BitsToDouble(IntVal)); + APFloat F(BitsToDouble(IntVal)); if (Minus) F.changeSign(); Operands.push_back( @@ -1153,8 +1153,12 @@ default: break; case Match_Success: Inst.setLoc(IDLoc); - Out.EmitInstruction(Inst, getSTI()); - return false; + if (!ProcessInstruction(Inst)) { + Out.EmitInstruction(Inst, getSTI()); + return false; + } else { + return true; + } case Match_MissingFeature: return Error(IDLoc, "instruction not supported on this GPU"); @@ -1531,6 +1535,112 @@ return false; } +bool AMDGPUAsmParser::ProcessInstruction(MCInst &Inst) { + // TODO: check that there is only one non-inline literal constant + const auto& InstDesc = MII.get(Inst.getOpcode()); + for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { + auto &Op = Inst.getOperand(i); // real operand that we got after parsing + + if (!(Op.isImm() || Op.isFPImm()) || + !AMDGPU::isSISrcOperand(InstDesc, i)) { + // Skip operand if it is not immediate or expected operand can't contain literal + continue; + } + + APInt Literal(64, Op.isImm() ? Op.getImm() : DoubleToBits(Op.getFPImm())); + auto OpSize = AMDGPU::getRegOperandSize(getRegisterInfo(), InstDesc, i); // expected operand size + bool ShouldInline = AMDGPU::isSISrcInlinableOperand(InstDesc, i); + + if (Op.isFPImm()) { // We got fp literal token + if (OpSize == 8) { // Expected 64-bit operand + // Check if literal is inlinable + if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(), isVI())) { + Op = MCOperand::createImm(Literal.getZExtValue()); + continue; + } + // Literal is not inlinable. + if (ShouldInline) { + return Error(Inst.getLoc(), "Can't encode floating-point literal." + " Only inlinable literals are allowed"); + } + if (AMDGPU::isSISrcFPOperand(InstDesc, i)) { // Expected 64-bit fp operand + // For fp operands we check if low 32 bits are zeros + if (Literal.getLoBits(32) != 0) { + Warning(Inst.getLoc(), "Can't encode literal as exact 64-bit" + " floating-point operand. Low 32-bits will be" + " set to zero"); + } + Op = MCOperand::createImm(Literal.lshr(32).getZExtValue()); + continue; + } else { // Expected 64-bit integer operand + // We don't allow fp literals in 64-bit integer instructions. It is + // unclear how we should encode them. + return Error(Inst.getLoc(), "Can't encode floating-point literal as" + " 64-bit integer operand. Only inlinable" + " floating-point literals are allowed"); + } + + } else { // Expected 32-bit operand + bool lost; + APFloat FPLiteral(Op.getFPImm()); + APFloat::opStatus status = FPLiteral.convert(APFloat::IEEEsingle, + APFloat::rmNearestTiesToEven, + &lost); + // We allow precision lost but not overflow or underflow + if (status != APFloat::opOK && + lost && + ((status & APFloat::opOverflow) != 0 || + (status & APFloat::opUnderflow) != 0)) { + return Error(Inst.getLoc(), "Can't encode literal as 32-bit operand"); + } + // Check if literal is inlinable + if (ShouldInline && + !AMDGPU::isInlinableLiteral32( + static_cast(FPLiteral.bitcastToAPInt().getZExtValue()), + isVI())) { + return Error(Inst.getLoc(), "Can't encode floating-point literal." + " Only inlinable literals are allowed"); + } + + // Any 32-bit literal can be encoded + Op = MCOperand::createImm(FPLiteral.bitcastToAPInt().getZExtValue()); + continue; + } + + } else { // We got integer literal token + // Check if literal is inlinable + if (OpSize == 8) { + if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(), isVI())) { + continue; + } + } else { + if (AMDGPU::isInlinableLiteral32( + static_cast(Literal.getLoBits(32).getZExtValue()), + isVI())) { + continue; + } + } + if (ShouldInline) { + return Error(Inst.getLoc(), "Can't encode integer literal." + " Only inlinable literals are allowed"); + } + + APInt HiBits = Literal.getHiBits(32); + if (HiBits == 0xffffffff && + (*Literal.getLoBits(32).getRawData() & 0x80000000) != 0) { + // If high 32 bits aren't zeroes then they all should be ones and 32nd + // bit should be set. So that this 64-bit literal is sign-extension of + // 32-bit value. + // If so we should nullify high 32 bits + Op = MCOperand::createImm(Literal.getLoBits(32).getZExtValue()); + } else if (HiBits != 0) { + return Error(Inst.getLoc(), "Can't encode literal operand"); + } + } + } + return false; +} + //===----------------------------------------------------------------------===// // Utility functions //===----------------------------------------------------------------------===// Index: lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp =================================================================== --- lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp +++ lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp @@ -359,7 +359,7 @@ else if (Imm == DoubleToBits(-4.0)) O << "-4.0"; else { - assert(isUInt<32>(Imm)); + assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882); // In rare situations, we will have a 32-bit literal in a 64-bit // operand. This is technically allowed for the encoding of s_mov_b64. Index: lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp +++ lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp @@ -18,6 +18,7 @@ #include "MCTargetDesc/AMDGPUMCCodeEmitter.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "SIDefines.h" +#include "Utils/AMDGPUBaseInfo.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCFixup.h" @@ -37,11 +38,9 @@ const MCInstrInfo &MCII; const MCRegisterInfo &MRI; - /// \brief Can this operand also contain immediate values? - bool isSrcOperand(const MCInstrDesc &Desc, unsigned OpNo) const; - /// \brief Encode an fp or int literal - uint32_t getLitEncoding(const MCOperand &MO, unsigned OpSize) const; + uint32_t getLitEncoding(const MCOperand &MO, unsigned OpSize, + const MCSubtargetInfo &STI) const; public: SIMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri, @@ -75,14 +74,6 @@ return new SIMCCodeEmitter(MCII, MRI, Ctx); } -bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc, - unsigned OpNo) const { - unsigned OpType = Desc.OpInfo[OpNo].OperandType; - - return OpType == AMDGPU::OPERAND_REG_IMM32 || - OpType == AMDGPU::OPERAND_REG_INLINE_C; -} - // Returns the encoding value to use if the given integer is an integer inline // immediate value, or 0 if it is not. template @@ -96,7 +87,7 @@ return 0; } -static uint32_t getLit32Encoding(uint32_t Val) { +static uint32_t getLit32Encoding(uint32_t Val, const MCSubtargetInfo &STI) { uint32_t IntImm = getIntInlineImmEncoding(static_cast(Val)); if (IntImm != 0) return IntImm; @@ -125,10 +116,13 @@ if (Val == FloatToBits(-4.0f)) return 247; + if (AMDGPU::isVI(STI) && Val == 0x3e22f983) // 1/(2*pi) + return 248; + return 255; } -static uint32_t getLit64Encoding(uint64_t Val) { +static uint32_t getLit64Encoding(uint64_t Val, const MCSubtargetInfo &STI) { uint32_t IntImm = getIntInlineImmEncoding(static_cast(Val)); if (IntImm != 0) return IntImm; @@ -157,11 +151,15 @@ if (Val == DoubleToBits(-4.0)) return 247; + if (AMDGPU::isVI(STI) && Val == 0x3fc45f306dc9c882) // 1/(2*pi) + return 248; + return 255; } uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO, - unsigned OpSize) const { + unsigned OpSize, + const MCSubtargetInfo &STI) const { int64_t Imm; if (MO.isExpr()) { @@ -181,11 +179,11 @@ } if (OpSize == 4) - return getLit32Encoding(static_cast(Imm)); + return getLit32Encoding(static_cast(Imm), STI); assert(OpSize == 8); - return getLit64Encoding(static_cast(Imm)); + return getLit64Encoding(static_cast(Imm), STI); } void SIMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, @@ -207,7 +205,7 @@ for (unsigned i = 0, e = MI.getNumOperands(); i < e; ++i) { // Check if this operand should be encoded as [SV]Src - if (!isSrcOperand(Desc, i)) + if (!AMDGPU::isSISrcOperand(Desc, i)) continue; int RCID = Desc.OpInfo[i].RegClass; @@ -215,7 +213,7 @@ // Is this operand a literal immediate? const MCOperand &Op = MI.getOperand(i); - if (getLitEncoding(Op, RC.getSize()) != 255) + if (getLitEncoding(Op, RC.getSize(), STI) != 255) continue; // Yes! Encode it @@ -279,11 +277,10 @@ } const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); - if (isSrcOperand(Desc, OpNo)) { - int RCID = Desc.OpInfo[OpNo].RegClass; - const MCRegisterClass &RC = MRI.getRegClass(RCID); - - uint32_t Enc = getLitEncoding(MO, RC.getSize()); + if (AMDGPU::isSISrcOperand(Desc, OpNo)) { + uint32_t Enc = getLitEncoding(MO, + AMDGPU::getRegOperandSize(&MRI, Desc, OpNo), + STI); if (Enc != ~0U && (Enc != 255 || Desc.getSize() == 4)) return Enc; Index: lib/Target/AMDGPU/SIDefines.h =================================================================== --- lib/Target/AMDGPU/SIDefines.h +++ lib/Target/AMDGPU/SIDefines.h @@ -48,10 +48,12 @@ namespace llvm { namespace AMDGPU { enum OperandType { - /// Operand with register or 32-bit immediate - OPERAND_REG_IMM32 = MCOI::OPERAND_FIRST_TARGET, - /// Operand with register or inline constant - OPERAND_REG_INLINE_C, + /// Operands with register or 32-bit immediate + OPERAND_REG_IMM32_INT = MCOI::OPERAND_FIRST_TARGET, + OPERAND_REG_IMM32_FP, + /// Operands with register or inline constant + OPERAND_REG_INLINE_C_INT, + OPERAND_REG_INLINE_C_FP, /// Operand with 32-bit immediate that uses the constant bus. The standard /// OPERAND_IMMEDIATE should be used for special immediates such as source Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -1686,9 +1686,11 @@ return false; } break; - case AMDGPU::OPERAND_REG_IMM32: + case AMDGPU::OPERAND_REG_IMM32_INT: + case AMDGPU::OPERAND_REG_IMM32_FP: break; - case AMDGPU::OPERAND_REG_INLINE_C: + case AMDGPU::OPERAND_REG_INLINE_C_INT: + case AMDGPU::OPERAND_REG_INLINE_C_FP: if (isLiteralConstant(MI.getOperand(i), RI.getRegClass(RegClass)->getSize())) { ErrInfo = "Illegal immediate value for operand."; @@ -2028,8 +2030,8 @@ // In order to be legal, the common sub-class must be equal to the // class of the current operand. For example: // - // v_mov_b32 s0 ; Operand defined as vsrc_32 - // ; RI.getCommonSubClass(s0,vsrc_32) = sgpr ; LEGAL + // v_mov_b32 s0 ; Operand defined as vsrc_b32 + // ; RI.getCommonSubClass(s0,vsrc_b32) = sgpr ; LEGAL // // s_sendmsg 0, s0 ; Operand defined as m0reg // ; RI.getCommonSubClass(s0,m0reg) = m0reg ; NOT LEGAL Index: lib/Target/AMDGPU/SIInstrInfo.td =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.td +++ lib/Target/AMDGPU/SIInstrInfo.td @@ -753,12 +753,12 @@ } multiclass SOP1_32 pattern> : SOP1_m < - op, opName, (outs SReg_32:$sdst), (ins SSrc_32:$src0), + op, opName, (outs SReg_32:$sdst), (ins SSrc_b32:$src0), opName#" $sdst, $src0", pattern >; multiclass SOP1_64 pattern> : SOP1_m < - op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0), + op, opName, (outs SReg_64:$sdst), (ins SSrc_b64:$src0), opName#" $sdst, $src0", pattern >; @@ -794,13 +794,13 @@ // 64-bit input, 32-bit output. multiclass SOP1_32_64 pattern> : SOP1_m < - op, opName, (outs SReg_32:$sdst), (ins SSrc_64:$src0), + op, opName, (outs SReg_32:$sdst), (ins SSrc_b64:$src0), opName#" $sdst, $src0", pattern >; // 32-bit input, 64-bit output. multiclass SOP1_64_32 pattern> : SOP1_m < - op, opName, (outs SReg_64:$sdst), (ins SSrc_32:$src0), + op, opName, (outs SReg_64:$sdst), (ins SSrc_b32:$src0), opName#" $sdst, $src0", pattern >; @@ -848,22 +848,22 @@ } multiclass SOP2_32 pattern> : SOP2_m < - op, opName, (outs SReg_32:$sdst), (ins SSrc_32:$src0, SSrc_32:$src1), + op, opName, (outs SReg_32:$sdst), (ins SSrc_b32:$src0, SSrc_b32:$src1), opName#" $sdst, $src0, $src1", pattern >; multiclass SOP2_64 pattern> : SOP2_m < - op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0, SSrc_64:$src1), + op, opName, (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b64:$src1), opName#" $sdst, $src0, $src1", pattern >; multiclass SOP2_64_32 pattern> : SOP2_m < - op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0, SSrc_32:$src1), + op, opName, (outs SReg_64:$sdst), (ins SSrc_b64:$src0, SSrc_b32:$src1), opName#" $sdst, $src0, $src1", pattern >; multiclass SOP2_64_32_32 pattern> : SOP2_m < - op, opName, (outs SReg_64:$sdst), (ins SSrc_32:$src0, SSrc_32:$src1), + op, opName, (outs SReg_64:$sdst), (ins SSrc_b32:$src0, SSrc_b32:$src1), opName#" $sdst, $src0, $src1", pattern >; @@ -880,13 +880,13 @@ } class SOPC_CMP_32 op, string opName, PatLeaf cond = COND_NULL> - : SOPC_Helper; + : SOPC_Helper; class SOPC_32 op, string opName, list pattern = []> - : SOPC_Base; + : SOPC_Base; class SOPC_64_32 op, string opName, list pattern = []> - : SOPC_Base; + : SOPC_Base; class SOPK_Pseudo pattern> : SOPK , @@ -1154,7 +1154,13 @@ // Returns the register class to use for source 0 of VOP[12C] // instructions for the given VT. class getVOPSrc0ForVT { - RegisterOperand ret = !if(!eq(VT.Size, 64), VSrc_64, VSrc_32); + bit isFP = !if(!eq(VT.Value, f16.Value), 1, + !if(!eq(VT.Value, f32.Value), 1, + !if(!eq(VT.Value, f64.Value), 1, + 0))); + RegisterOperand ret = !if(isFP, + !if(!eq(VT.Size, 64), VSrc_f64, VSrc_f32), + !if(!eq(VT.Size, 64), VSrc_b64, VSrc_b32)); } // Returns the vreg register class to use for source operand given VT @@ -1166,14 +1172,22 @@ // Returns the register class to use for sources of VOP3 instructions for the // given VT. class getVOP3SrcForVT { + bit isFP = !if(!eq(VT.Value, f16.Value), 1, + !if(!eq(VT.Value, f32.Value), 1, + !if(!eq(VT.Value, f64.Value), 1, + 0))); RegisterOperand ret = - !if(!eq(VT.Size, 64), - VCSrc_64, - !if(!eq(VT.Value, i1.Value), - SCSrc_64, - VCSrc_32 - ) - ); + !if(!eq(VT.Size, 64), + !if(isFP, + VCSrc_f64, + VCSrc_b64), + !if(!eq(VT.Value, i1.Value), + SCSrc_b64, + !if(isFP, + VCSrc_f32, + VCSrc_b32) + ) + ); } // Returns 1 if the source arguments have modifiers, 0 if they do not. @@ -1517,12 +1531,12 @@ let Src0RC64 = VOPDstOperand; let Outs = (outs); - let Ins32 = (ins Src0RC32:$vdst, VSrc_32:$src0); - let Ins64 = (ins Src0RC64:$vdst, VSrc_32:$src0); + let Ins32 = (ins Src0RC32:$vdst, VSrc_b32:$src0); + let Ins64 = (ins Src0RC64:$vdst, VSrc_b32:$src0); let InsDPP = (ins Src0RC32:$vdst, Src0RC32:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask, bank_mask:$bank_mask, bound_ctrl:$bound_ctrl); - let InsSDWA = (ins Src0RC32:$vdst, IntInputMods:$src0_imodifiers, VCSrc_32:$src0, + let InsSDWA = (ins Src0RC32:$vdst, IntInputMods:$src0_imodifiers, VCSrc_b32:$src0, clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused, src0_sel:$src0_sel); @@ -1546,12 +1560,12 @@ // Write out to vcc or arbitrary SGPR and read in from vcc or // arbitrary SGPR. def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { - // We use VCSrc_32 to exclude literal constants, even though the + // We use VCSrc_b32 to exclude literal constants, even though the // encoding normally allows them since the implicit VCC use means // using one would always violate the constant bus // restriction. SGPRs are still allowed because it should // technically be possible to use VCC again as src0. - let Src0RC32 = VCSrc_32; + let Src0RC32 = VCSrc_b32; let Asm32 = "$vdst, vcc, $src0, $src1, vcc"; let Asm64 = "$vdst, $sdst, $src0, $src1, $src2"; let Outs32 = (outs DstRC:$vdst); @@ -1564,7 +1578,7 @@ // Read in from vcc or arbitrary SGPR def VOP2e_I32_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> { - let Src0RC32 = VCSrc_32; // See comment in def VOP2b_I32_I1_I32_I32_I1 above. + let Src0RC32 = VCSrc_b32; // See comment in def VOP2b_I32_I1_I32_I32_I1 above. let Asm32 = "$vdst, $src0, $src1, vcc"; let Asm64 = "$vdst, $src0, $src1, $src2"; let Outs32 = (outs DstRC:$vdst); @@ -1624,12 +1638,12 @@ def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>; def VOP_MADAK : VOPProfile <[f32, f32, f32, f32]> { - field dag Ins32 = (ins VCSrc_32:$src0, VGPR_32:$src1, u32kimm:$imm); + field dag Ins32 = (ins VCSrc_f32:$src0, VGPR_32:$src1, u32kimm:$imm); field string Asm32 = "$vdst, $src0, $src1, $imm"; field bit HasExt = 0; } def VOP_MADMK : VOPProfile <[f32, f32, f32, f32]> { - field dag Ins32 = (ins VCSrc_32:$src0, u32kimm:$imm, VGPR_32:$src1); + field dag Ins32 = (ins VCSrc_f32:$src0, u32kimm:$imm, VGPR_32:$src1); field string Asm32 = "$vdst, $src0, $imm, $src1"; field bit HasExt = 0; } @@ -2891,7 +2905,7 @@ op, opName, (outs), (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, - SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset), + SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_b32:$soffset), opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt," #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", [] >; @@ -2905,7 +2919,7 @@ op, opName, (outs regClass:$dst), (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc, - i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset), + i1imm:$slc, i1imm:$tfe, SCSrc_b32:$soffset), opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt," #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", [] >; @@ -3062,13 +3076,13 @@ defm _ADDR64 : MUBUFAtomicAddr64_m < op, name#"_addr64", (outs), (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, - SCSrc_32:$soffset, offset:$offset, slc:$slc), + SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset$slc", [], 0 >; defm _OFFSET : MUBUFAtomicOffset_m < op, name#"_offset", (outs), - (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, offset:$offset, + (ins rc:$vdata, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, off, $srsrc, $soffset$offset$slc", [], 0 >; @@ -3076,7 +3090,7 @@ let offen = 1, idxen = 0 in { defm _OFFEN : MUBUFAtomicOther_m < op, name#"_offen", (outs), - (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, + (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset offen$offset$slc", [], 0 >; @@ -3085,7 +3099,7 @@ let offen = 0, idxen = 1 in { defm _IDXEN : MUBUFAtomicOther_m < op, name#"_idxen", (outs), - (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, + (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset$slc", [], 0 >; @@ -3094,7 +3108,7 @@ let offen = 1, idxen = 1 in { defm _BOTHEN : MUBUFAtomicOther_m < op, name#"_bothen", (outs), - (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, + (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset$slc", [], 0 @@ -3110,7 +3124,7 @@ defm _RTN_ADDR64 : MUBUFAtomicAddr64_m < op, name#"_rtn_addr64", (outs rc:$vdata), (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, - SCSrc_32:$soffset, offset:$offset, slc:$slc), + SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset addr64$offset glc$slc", [(set vt:$vdata, (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset, @@ -3119,7 +3133,7 @@ defm _RTN_OFFSET : MUBUFAtomicOffset_m < op, name#"_rtn_offset", (outs rc:$vdata), - (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset, + (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, off, $srsrc, $soffset$offset glc$slc", [(set vt:$vdata, @@ -3130,7 +3144,7 @@ let offen = 1, idxen = 0 in { defm _RTN_OFFEN : MUBUFAtomicOther_m < op, name#"_rtn_offen", (outs rc:$vdata), - (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, + (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset offen$offset glc$slc", [], 1 @@ -3140,7 +3154,7 @@ let offen = 0, idxen = 1 in { defm _RTN_IDXEN : MUBUFAtomicOther_m < op, name#"_rtn_idxen", (outs rc:$vdata), - (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, + (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset idxen$offset glc$slc", [], 1 @@ -3150,7 +3164,7 @@ let offen = 1, idxen = 1 in { defm _RTN_BOTHEN : MUBUFAtomicOther_m < op, name#"_rtn_bothen", (outs rc:$vdata), - (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset, + (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_b32:$soffset, offset:$offset, slc:$slc), name#" $vdata, $vaddr, $srsrc, $soffset idxen offen$offset glc$slc", [], 1 @@ -3170,7 +3184,7 @@ let mayLoad = 1, mayStore = 0 in { let offen = 0, idxen = 0, vaddr = 0 in { defm _OFFSET : MUBUF_m ; } @@ -3189,14 +3203,14 @@ let offen = 0, idxen = 1 in { defm _IDXEN : MUBUF_m ; } let offen = 1, idxen = 1 in { defm _BOTHEN : MUBUF_m ; } @@ -3204,7 +3218,7 @@ let offen = 0, idxen = 0 in { defm _ADDR64 : MUBUFAddr64_m ; @@ -3239,14 +3253,14 @@ let offen = 0, idxen = 1 in { defm _IDXEN : MUBUF_m ; } let offen = 1, idxen = 1 in { defm _BOTHEN : MUBUF_m ; } @@ -3254,7 +3268,7 @@ let offen = 0, idxen = 0 in { defm _ADDR64 : MUBUFAddr64_m , "s_add_u32", []>; defm S_ADD_I32 : SOP2_32 , "s_add_i32", - [(set i32:$sdst, (add SSrc_32:$src0, SSrc_32:$src1))] + [(set i32:$sdst, (add SSrc_b32:$src0, SSrc_b32:$src1))] >; } // End isCommutable = 1 defm S_SUB_U32 : SOP2_32 , "s_sub_u32", []>; defm S_SUB_I32 : SOP2_32 , "s_sub_i32", - [(set i32:$sdst, (sub SSrc_32:$src0, SSrc_32:$src1))] + [(set i32:$sdst, (sub SSrc_b32:$src0, SSrc_b32:$src1))] >; let Uses = [SCC] in { // Carry in comes from SCC let isCommutable = 1 in { defm S_ADDC_U32 : SOP2_32 , "s_addc_u32", - [(set i32:$sdst, (adde (i32 SSrc_32:$src0), (i32 SSrc_32:$src1)))]>; + [(set i32:$sdst, (adde (i32 SSrc_b32:$src0), (i32 SSrc_b32:$src1)))]>; } // End isCommutable = 1 defm S_SUBB_U32 : SOP2_32 , "s_subb_u32", - [(set i32:$sdst, (sube (i32 SSrc_32:$src0), (i32 SSrc_32:$src1)))]>; + [(set i32:$sdst, (sube (i32 SSrc_b32:$src0), (i32 SSrc_b32:$src1)))]>; } // End Uses = [SCC] defm S_MIN_I32 : SOP2_32 , "s_min_i32", @@ -1594,7 +1594,7 @@ vop3 <0x001, 0x289>, "v_readlane_b32", (outs SReg_32:$vdst), - (ins VS_32:$src0, SCSrc_32:$src1), + (ins VS_32:$src0, SCSrc_b32:$src1), "v_readlane_b32 $vdst, $src0, $src1" >; @@ -1602,7 +1602,7 @@ vop3 <0x002, 0x28a>, "v_writelane_b32", (outs VGPR_32:$vdst), - (ins SReg_32:$src0, SCSrc_32:$src1), + (ins SReg_32:$src0, SCSrc_b32:$src1), "v_writelane_b32 $vdst, $src0, $src1" >; @@ -1909,14 +1909,14 @@ // For use in patterns def V_CNDMASK_B64_PSEUDO : VOP3Common <(outs VReg_64:$vdst), - (ins VSrc_64:$src0, VSrc_64:$src1, SSrc_64:$src2), "", []> { + (ins VSrc_b64:$src0, VSrc_b64:$src1, SSrc_b64:$src2), "", []> { let isPseudo = 1; let isCodeGenOnly = 1; } // 64-bit vector move instruction. This is mainly used by the SIFoldOperands // pass to enable folding of inline immediates. -def V_MOV_B64_PSEUDO : PseudoInstSI <(outs VReg_64:$vdst), (ins VSrc_64:$src0)> { +def V_MOV_B64_PSEUDO : PseudoInstSI <(outs VReg_64:$vdst), (ins VSrc_b64:$src0)> { let VALU = 1; } } // End let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [EXEC] @@ -1988,14 +1988,14 @@ let Uses = [EXEC], Defs = [EXEC,VCC] in { def SI_KILL : PseudoInstSI < - (outs), (ins VSrc_32:$src), + (outs), (ins VSrc_b32:$src), [(AMDGPUkill i32:$src)]> { let isConvergent = 1; let usesCustomInserter = 1; } def SI_KILL_TERMINATOR : PseudoInstSI < - (outs), (ins VSrc_32:$src)> { + (outs), (ins VSrc_b32:$src)> { let isTerminator = 1; } @@ -2013,7 +2013,7 @@ // s_mov_b32 rather than a copy of another initialized // register. MachineCSE skips copies, and we don't want to have to // fold operands before it runs. -def SI_INIT_M0 : PseudoInstSI <(outs), (ins SSrc_32:$src)> { +def SI_INIT_M0 : PseudoInstSI <(outs), (ins SSrc_b32:$src)> { let Defs = [M0]; let usesCustomInserter = 1; let isAsCheapAsAMove = 1; Index: lib/Target/AMDGPU/SIRegisterInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIRegisterInfo.cpp +++ lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -892,14 +892,16 @@ } bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const { - return OpType == AMDGPU::OPERAND_REG_IMM32; + return OpType == AMDGPU::OPERAND_REG_IMM32_INT || + OpType == AMDGPU::OPERAND_REG_IMM32_FP; } bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const { if (opCanUseLiteralConstant(OpType)) return true; - return OpType == AMDGPU::OPERAND_REG_INLINE_C; + return OpType == AMDGPU::OPERAND_REG_INLINE_C_INT || + OpType == AMDGPU::OPERAND_REG_INLINE_C_FP; } // FIXME: Most of these are flexible with HSA and we don't need to reserve them Index: lib/Target/AMDGPU/SIRegisterInfo.td =================================================================== --- lib/Target/AMDGPU/SIRegisterInfo.td +++ lib/Target/AMDGPU/SIRegisterInfo.td @@ -349,56 +349,59 @@ // Register operands //===----------------------------------------------------------------------===// -class RegImmOperand : RegisterOperand { - let OperandNamespace = "AMDGPU"; - let OperandType = "OPERAND_REG_IMM32"; -} - -class RegInlineOperand : RegisterOperand { - let OperandNamespace = "AMDGPU"; - let OperandType = "OPERAND_REG_INLINE_C"; -} - class RegImmMatcher : AsmOperandClass { let Name = name; let RenderMethod = "addRegOrImmOperands"; } +multiclass SIRegOperand { + let OperandNamespace = "AMDGPU" in { + + let ParserMatchClass = RegImmMatcher in { + def _b32 : RegisterOperand(rc#"_32")> { + let OperandType = opType#"_INT"; + } + + def _f32 : RegisterOperand(rc#"_32")> { + let OperandType = opType#"_FP"; + } + } + + let ParserMatchClass = RegImmMatcher in { + def _b64 : RegisterOperand(rc#"_64")> { + let OperandType = opType#"_INT"; + } + + def _f64 : RegisterOperand(rc#"_64")> { + let OperandType = opType#"_FP"; + } + } + } +} + +multiclass RegImmOperand + : SIRegOperand; + +multiclass RegInlineOperand + : SIRegOperand; + //===----------------------------------------------------------------------===// // SSrc_* Operands with an SGPR or a 32-bit immediate //===----------------------------------------------------------------------===// -def SSrc_32 : RegImmOperand { - let ParserMatchClass = RegImmMatcher<"SSrc32">; -} - -def SSrc_64 : RegImmOperand { - let ParserMatchClass = RegImmMatcher<"SSrc64">; -} +defm SSrc : RegImmOperand<"SReg", "SSrc">; //===----------------------------------------------------------------------===// // SCSrc_* Operands with an SGPR or a inline constant //===----------------------------------------------------------------------===// -def SCSrc_32 : RegInlineOperand { - let ParserMatchClass = RegImmMatcher<"SCSrc32">; -} - -def SCSrc_64 : RegInlineOperand { - let ParserMatchClass = RegImmMatcher<"SCSrc64">; -} +defm SCSrc : RegInlineOperand<"SReg", "SCSrc"> ; //===----------------------------------------------------------------------===// // VSrc_* Operands with an SGPR, VGPR or a 32-bit immediate //===----------------------------------------------------------------------===// -def VSrc_32 : RegImmOperand { - let ParserMatchClass = RegImmMatcher<"VSrc32">; -} - -def VSrc_64 : RegImmOperand { - let ParserMatchClass = RegImmMatcher<"VSrc64">; -} +defm VSrc : RegImmOperand<"VS", "VSrc">; //===----------------------------------------------------------------------===// // VSrc_* Operands with an VGPR @@ -415,10 +418,4 @@ // VCSrc_* Operands with an SGPR, VGPR or an inline constant //===----------------------------------------------------------------------===// -def VCSrc_32 : RegInlineOperand { - let ParserMatchClass = RegImmMatcher<"VCSrc32">; -} - -def VCSrc_64 : RegInlineOperand { - let ParserMatchClass = RegImmMatcher<"VCSrc64">; -} +defm VCSrc : RegInlineOperand<"VS", "VCSrc">; Index: lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h =================================================================== --- lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -19,6 +19,8 @@ class Function; class GlobalValue; class MCContext; +class MCInstrDesc; +class MCRegisterInfo; class MCSection; class MCSubtargetInfo; @@ -61,6 +63,23 @@ /// \p STI otherwise return \p Reg. unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI); +/// \brief Can this operand also contain immediate values? +bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo); + +/// \brief Is this floating-point operand? +bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo); + +/// \brief Does this opearnd support only inlinable literals? +bool isSISrcInlinableOperand(const MCInstrDesc &Desc, unsigned OpNo); + +/// \brief Get size of register operand +unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, + unsigned OpNo); + +/// \brief Is this literal inlinable +bool isInlinableLiteral64(int64_t Literal, bool IsVI); +bool isInlinableLiteral32(int32_t Literal, bool IsVI); + } // end namespace AMDGPU } // end namespace llvm Index: lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp =================================================================== --- lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -8,10 +8,13 @@ //===----------------------------------------------------------------------===// #include "AMDGPUBaseInfo.h" #include "AMDGPU.h" +#include "SIDefines.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/SubtargetFeature.h" @@ -179,5 +182,72 @@ return Reg; } +bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo) { + unsigned OpType = Desc.OpInfo[OpNo].OperandType; + + return OpType == AMDGPU::OPERAND_REG_IMM32_INT || + OpType == AMDGPU::OPERAND_REG_IMM32_FP || + OpType == AMDGPU::OPERAND_REG_INLINE_C_INT || + OpType == AMDGPU::OPERAND_REG_INLINE_C_FP; +} + +bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo) { + unsigned OpType = Desc.OpInfo[OpNo].OperandType; + + return OpType == AMDGPU::OPERAND_REG_IMM32_FP || + OpType == AMDGPU::OPERAND_REG_INLINE_C_FP; +} + +bool isSISrcInlinableOperand(const MCInstrDesc &Desc, unsigned OpNo) { + unsigned OpType = Desc.OpInfo[OpNo].OperandType; + + return OpType == AMDGPU::OPERAND_REG_INLINE_C_INT || + OpType == AMDGPU::OPERAND_REG_INLINE_C_FP; +} + +unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, + unsigned OpNo) { + int RCID = Desc.OpInfo[OpNo].RegClass; + const MCRegisterClass &RC = MRI->getRegClass(RCID); + return RC.getSize(); +} + +bool isInlinableLiteral64(int64_t Literal, bool IsVI) { + if (Literal >= -16 && Literal <= 64) + return true; + + double D = BitsToDouble(Literal); + + if (D == 0.5 || D == -0.5 || + D == 1.0 || D == -1.0 || + D == 2.0 || D == -2.0 || + D == 4.0 || D == -4.0) + return true; + + if (IsVI && Literal == 0x3fc45f306dc9c882) + return true; + + return false; +} + +bool isInlinableLiteral32(int32_t Literal, bool IsVI) { + if (Literal >= -16 && Literal <= 64) + return true; + + float F = BitsToFloat(Literal); + + if (F == 0.5 || F == -0.5 || + F == 1.0 || F == -1.0 || + F == 2.0 || F == -2.0 || + F == 4.0 || F == -4.0) + return true; + + if (IsVI && Literal == 0x3e22f983) + return true; + + return false; +} + + } // End namespace AMDGPU } // End namespace llvm Index: lib/Target/AMDGPU/VIInstructions.td =================================================================== --- lib/Target/AMDGPU/VIInstructions.td +++ lib/Target/AMDGPU/VIInstructions.td @@ -90,7 +90,7 @@ class SI2_VI3Alias : InstAlias < name#" $dst, $src0, $src1", - (inst VGPR_32:$dst, 0, VCSrc_32:$src0, 0, VCSrc_32:$src1, 0, 0) + (inst VGPR_32:$dst, 0, VCSrc_f32:$src0, 0, VCSrc_f32:$src1, 0, 0) >, PredicateControl { let UseInstAsmMatchConverter = 0; } Index: test/MC/AMDGPU/regression/bug28165.s =================================================================== --- /dev/null +++ test/MC/AMDGPU/regression/bug28165.s @@ -0,0 +1,495 @@ +// RUN: not llvm-mc -arch=amdgcn -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=SI --check-prefix=SICI +// RUN: not llvm-mc -arch=amdgcn -mcpu=SI -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=SI --check-prefix=SICI +// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=SICI --check-prefix=CIVI +// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=CIVI --check-prefix=VI + +// RUN: not llvm-mc -arch=amdgcn -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSI --check-prefix=NOSICI +// RUN: not llvm-mc -arch=amdgcn -mcpu=SI -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSI --check-prefix=NOSICI +// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSICI +// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck %s -check-prefix=NOVI + +//---------------------------------------------------------------------------// +// fp literal, expected fp operand +//---------------------------------------------------------------------------// + +// SICI: v_cmp_eq_f64_e32 vcc, 0.5, v[254:255] ; encoding: [0xf0,0xfc,0x45,0x7c] +// VI: v_cmp_eq_f64_e32 vcc, 0.5, v[254:255] ; encoding: [0xf0,0xfc,0xc5,0x7c] +v_cmp_eq_f64 vcc, 0.5, v[254:255] + +// GCN: v_cvt_f32_f64_e32 v0, 0.5 ; encoding: [0xf0,0x1e,0x00,0x7e] +v_cvt_f32_f64 v0, 0.5 + +// SICI: v_fract_f64_e32 v[0:1], 0.5 ; encoding: [0xf0,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], 0.5 ; encoding: [0xf0,0x64,0x00,0x7e] +v_fract_f64 v[0:1], 0.5 + +// SICI: v_sqrt_f64_e32 v[0:1], -4.0 ; encoding: [0xf7,0x68,0x00,0x7e] +// VI: v_sqrt_f64_e32 v[0:1], -4.0 ; encoding: [0xf7,0x50,0x00,0x7e] +v_sqrt_f64 v[0:1], -4.0 + +// SICI: v_log_clamp_f32_e32 v1, 0.5 ; encoding: [0xf0,0x4c,0x02,0x7e] +// NOVI: error: instruction not supported on this GPU +v_log_clamp_f32 v1, 0.5 + +// SICI: v_fract_f64_e32 v[0:1], 0.5 ; encoding: [0xf0,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], 0.5 ; encoding: [0xf0,0x64,0x00,0x7e] +v_fract_f64 v[0:1], 0.5 + +// SICI: v_trunc_f32_e32 v0, 0.5 ; encoding: [0xf0,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, 0.5 ; encoding: [0xf0,0x38,0x00,0x7e] +v_trunc_f32 v0, 0.5 + +// SICI: v_fract_f64_e32 v[0:1], -1.0 ; encoding: [0xf3,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], -1.0 ; encoding: [0xf3,0x64,0x00,0x7e] +v_fract_f64 v[0:1], -1.0 + +// SICI: v_trunc_f32_e32 v0, -1.0 ; encoding: [0xf3,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, -1.0 ; encoding: [0xf3,0x38,0x00,0x7e] +v_trunc_f32 v0, -1.0 + +// SICI: v_fract_f64_e32 v[0:1], 4.0 ; encoding: [0xf6,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], 4.0 ; encoding: [0xf6,0x64,0x00,0x7e] +v_fract_f64 v[0:1], 4.0 + +// SICI: v_trunc_f32_e32 v0, 4.0 ; encoding: [0xf6,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, 4.0 ; encoding: [0xf6,0x38,0x00,0x7e] +v_trunc_f32 v0, 4.0 + +// SICI: v_fract_f64_e32 v[0:1], 0 ; encoding: [0x80,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], 0 ; encoding: [0x80,0x64,0x00,0x7e] +v_fract_f64 v[0:1], 0.0 + +// SICI: v_trunc_f32_e32 v0, 0 ; encoding: [0x80,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, 0 ; encoding: [0x80,0x38,0x00,0x7e] +v_trunc_f32 v0, 0.0 + +// SICI: v_fract_f64_e32 v[0:1], 0x3ff80000 ; encoding: [0xff,0x7c,0x00,0x7e,0x00,0x00,0xf8,0x3f] +// VI: v_fract_f64_e32 v[0:1], 0x3ff80000 ; encoding: [0xff,0x64,0x00,0x7e,0x00,0x00,0xf8,0x3f] +v_fract_f64 v[0:1], 1.5 + +// SICI: v_trunc_f32_e32 v0, 0x3fc00000 ; encoding: [0xff,0x42,0x00,0x7e,0x00,0x00,0xc0,0x3f] +// VI: v_trunc_f32_e32 v0, 0x3fc00000 ; encoding: [0xff,0x38,0x00,0x7e,0x00,0x00,0xc0,0x3f] +v_trunc_f32 v0, 1.5 + +// NOSICI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// SICI: v_fract_f64_e32 v[0:1], 0xc00921ca ; encoding: [0xff,0x7c,0x00,0x7e,0xca,0x21,0x09,0xc0] +// NOVI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// VI: v_fract_f64_e32 v[0:1], 0xc00921ca ; encoding: [0xff,0x64,0x00,0x7e,0xca,0x21,0x09,0xc0] +v_fract_f64 v[0:1], -3.1415 + +// SICI: v_trunc_f32_e32 v0, 0xc0490e56 ; encoding: [0xff,0x42,0x00,0x7e,0x56,0x0e,0x49,0xc0] +// VI: v_trunc_f32_e32 v0, 0xc0490e56 ; encoding: [0xff,0x38,0x00,0x7e,0x56,0x0e,0x49,0xc0] +v_trunc_f32 v0, -3.1415 + +// NOSICI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// SICI: v_fract_f64_e32 v[0:1], 0x44b52d02 ; encoding: [0xff,0x7c,0x00,0x7e,0x02,0x2d,0xb5,0x44] +// NOVI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// VI: v_fract_f64_e32 v[0:1], 0x44b52d02 ; encoding: [0xff,0x64,0x00,0x7e,0x02,0x2d,0xb5,0x44] +v_fract_f64 v[0:1], 100000000000000000000000.0 + +// SICI: v_trunc_f32_e32 v0, 0x65a96816 ; encoding: [0xff,0x42,0x00,0x7e,0x16,0x68,0xa9,0x65] +// VI: v_trunc_f32_e32 v0, 0x65a96816 ; encoding: [0xff,0x38,0x00,0x7e,0x16,0x68,0xa9,0x65] +v_trunc_f32 v0, 100000000000000000000000.0 + +// SICI: v_fract_f64_e32 v[0:1], 0x416312d0 ; encoding: [0xff,0x7c,0x00,0x7e,0xd0,0x12,0x63,0x41] +// VI: v_fract_f64_e32 v[0:1], 0x416312d0 ; encoding: [0xff,0x64,0x00,0x7e,0xd0,0x12,0x63,0x41] +v_fract_f64 v[0:1], 10000000.0 + +// SICI: v_trunc_f32_e32 v0, 0x4b189680 ; encoding: [0xff,0x42,0x00,0x7e,0x80,0x96,0x18,0x4b] +// VI: v_trunc_f32_e32 v0, 0x4b189680 ; encoding: [0xff,0x38,0x00,0x7e,0x80,0x96,0x18,0x4b] +v_trunc_f32 v0, 10000000.0 + +// NOSICI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// SICI: v_fract_f64_e32 v[0:1], 0x47efffff ; encoding: [0xff,0x7c,0x00,0x7e,0xff,0xff,0xef,0x47] +// NOVI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// VI: v_fract_f64_e32 v[0:1], 0x47efffff ; encoding: [0xff,0x64,0x00,0x7e,0xff,0xff,0xef,0x47] +v_fract_f64 v[0:1], 3.402823e+38 + +// SICI: v_trunc_f32_e32 v0, 0x7f7ffffd ; encoding: [0xff,0x42,0x00,0x7e,0xfd,0xff,0x7f,0x7f] +// VI: v_trunc_f32_e32 v0, 0x7f7ffffd ; encoding: [0xff,0x38,0x00,0x7e,0xfd,0xff,0x7f,0x7f] +v_trunc_f32 v0, 3.402823e+38 + +// NOSICI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// SICI: v_fract_f64_e32 v[0:1], 0x381fffff ; encoding: [0xff,0x7c,0x00,0x7e,0xff,0xff,0x1f,0x38] +// NOVI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// VI: v_fract_f64_e32 v[0:1], 0x381fffff ; encoding: [0xff,0x64,0x00,0x7e,0xff,0xff,0x1f,0x38] +v_fract_f64 v[0:1], 2.3509886e-38 + +// SICI: v_trunc_f32_e32 v0, 0xffffff ; encoding: [0xff,0x42,0x00,0x7e,0xff,0xff,0xff,0x00] +// VI: v_trunc_f32_e32 v0, 0xffffff ; encoding: [0xff,0x38,0x00,0x7e,0xff,0xff,0xff,0x00] +v_trunc_f32 v0, 2.3509886e-38 + +// NOSICI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// SICI: v_fract_f64_e32 v[0:1], 0x3179f623 ; encoding: [0xff,0x7c,0x00,0x7e,0x23,0xf6,0x79,0x31] +// NOVI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// VI: v_fract_f64_e32 v[0:1], 0x3179f623 ; encoding: [0xff,0x64,0x00,0x7e,0x23,0xf6,0x79,0x31] +v_fract_f64 v[0:1], 2.3509886e-70 + +// NOSICI: error: Can't encode literal as 32-bit operand +// NOVI: error: Can't encode literal as 32-bit operand +v_trunc_f32 v0, 2.3509886e-70 + +//---------------------------------------------------------------------------// +// fp literal, expected int operand +//---------------------------------------------------------------------------// + +// SICI: s_mov_b64 s[0:1], 0.5 ; encoding: [0xf0,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], 0.5 ; encoding: [0xf0,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], 0.5 + +// SICI: v_and_b32_e32 v0, 0.5, v1 ; encoding: [0xf0,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, 0.5, v1 ; encoding: [0xf0,0x02,0x00,0x26] +v_and_b32_e32 v0, 0.5, v1 + +// SICI: v_and_b32_e64 v0, 0.5, v1 ; encoding: [0x00,0x00,0x36,0xd2,0xf0,0x02,0x02,0x00] +// VI: v_and_b32_e64 v0, 0.5, v1 ; encoding: [0x00,0x00,0x13,0xd1,0xf0,0x02,0x02,0x00] +v_and_b32_e64 v0, 0.5, v1 + +// SICI: s_mov_b64 s[0:1], -1.0 ; encoding: [0xf3,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], -1.0 ; encoding: [0xf3,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], -1.0 + +// SICI: v_and_b32_e32 v0, -1.0, v1 ; encoding: [0xf3,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, -1.0, v1 ; encoding: [0xf3,0x02,0x00,0x26] +v_and_b32_e32 v0, -1.0, v1 + +// SICI: v_and_b32_e64 v0, -1.0, v1 ; encoding: [0x00,0x00,0x36,0xd2,0xf3,0x02,0x02,0x00] +// VI: v_and_b32_e64 v0, -1.0, v1 ; encoding: [0x00,0x00,0x13,0xd1,0xf3,0x02,0x02,0x00] +v_and_b32_e64 v0, -1.0, v1 + +// SICI: s_mov_b64 s[0:1], 4.0 ; encoding: [0xf6,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], 4.0 ; encoding: [0xf6,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], 4.0 + +// SICI: v_and_b32_e32 v0, 4.0, v1 ; encoding: [0xf6,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, 4.0, v1 ; encoding: [0xf6,0x02,0x00,0x26] +v_and_b32_e32 v0, 4.0, v1 + +// SICI: v_and_b32_e64 v0, 4.0, v1 ; encoding: [0x00,0x00,0x36,0xd2,0xf6,0x02,0x02,0x00] +// VI: v_and_b32_e64 v0, 4.0, v1 ; encoding: [0x00,0x00,0x13,0xd1,0xf6,0x02,0x02,0x00] +v_and_b32_e64 v0, 4.0, v1 + +// SICI: s_mov_b64 s[0:1], 0 ; encoding: [0x80,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], 0 ; encoding: [0x80,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], 0.0 + +// SICI: v_and_b32_e32 v0, 0, v1 ; encoding: [0x80,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, 0, v1 ; encoding: [0x80,0x02,0x00,0x26] +v_and_b32_e32 v0, 0.0, v1 + +// SICI: v_and_b32_e64 v0, 0, v1 ; encoding: [0x00,0x00,0x36,0xd2,0x80,0x02,0x02,0x00] +// VI: v_and_b32_e64 v0, 0, v1 ; encoding: [0x00,0x00,0x13,0xd1,0x80,0x02,0x02,0x00] +v_and_b32_e64 v0, 0.0, v1 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// NOVI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +s_mov_b64_e32 s[0:1], 1.5 + +// SICI: v_and_b32_e32 v0, 0x3fc00000, v1 ; encoding: [0xff,0x02,0x00,0x36,0x00,0x00,0xc0,0x3f] +// VI: v_and_b32_e32 v0, 0x3fc00000, v1 ; encoding: [0xff,0x02,0x00,0x26,0x00,0x00,0xc0,0x3f] +v_and_b32_e32 v0, 1.5, v1 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// NOVI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +s_mov_b64_e32 s[0:1], -3.1415 + +// SICI: v_and_b32_e32 v0, 0xc0490e56, v1 ; encoding: [0xff,0x02,0x00,0x36,0x56,0x0e,0x49,0xc0] +// VI: v_and_b32_e32 v0, 0xc0490e56, v1 ; encoding: [0xff,0x02,0x00,0x26,0x56,0x0e,0x49,0xc0] +v_and_b32_e32 v0, -3.1415, v1 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// NOVI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +s_mov_b64_e32 s[0:1], 100000000000000000000000.0 + +// SICI: v_and_b32_e32 v0, 0x65a96816, v1 ; encoding: [0xff,0x02,0x00,0x36,0x16,0x68,0xa9,0x65] +// VI: v_and_b32_e32 v0, 0x65a96816, v1 ; encoding: [0xff,0x02,0x00,0x26,0x16,0x68,0xa9,0x65] +v_and_b32_e32 v0, 100000000000000000000000.0, v1 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// NOVI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +s_mov_b64_e32 s[0:1], 10000000.0 + +// SICI: v_and_b32_e32 v0, 0x4b189680, v1 ; encoding: [0xff,0x02,0x00,0x36,0x80,0x96,0x18,0x4b] +// VI: v_and_b32_e32 v0, 0x4b189680, v1 ; encoding: [0xff,0x02,0x00,0x26,0x80,0x96,0x18,0x4b] +v_and_b32_e32 v0, 10000000.0, v1 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// NOVI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +s_mov_b64_e32 s[0:1], 3.402823e+38 + +// SICI: v_and_b32_e32 v0, 0x7f7ffffd, v1 ; encoding: [0xff,0x02,0x00,0x36,0xfd,0xff,0x7f,0x7f] +// VI: v_and_b32_e32 v0, 0x7f7ffffd, v1 ; encoding: [0xff,0x02,0x00,0x26,0xfd,0xff,0x7f,0x7f] +v_and_b32_e32 v0, 3.402823e+38, v1 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// NOVI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +s_mov_b64_e32 s[0:1], 2.3509886e-38 + +// SICI: v_and_b32_e32 v0, 0xffffff, v1 ; encoding: [0xff,0x02,0x00,0x36,0xff,0xff,0xff,0x00] +// VI: v_and_b32_e32 v0, 0xffffff, v1 ; encoding: [0xff,0x02,0x00,0x26,0xff,0xff,0xff,0x00] +v_and_b32_e32 v0, 2.3509886e-38, v1 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// NOVI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +s_mov_b64_e32 s[0:1], 2.3509886e-70 + +// NOSICI: error: Can't encode literal as 32-bit operand +// NOVI: error: Can't encode literal as 32-bit operand +v_and_b32_e32 v0, 2.3509886e-70, v1 + +//---------------------------------------------------------------------------// +// int literal, expected fp operand +//---------------------------------------------------------------------------// + +// SICI: v_trunc_f32_e32 v0, 0 ; encoding: [0x80,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, 0 ; encoding: [0x80,0x38,0x00,0x7e] +v_trunc_f32_e32 v0, 0 + +// SICI: v_fract_f64_e32 v[0:1], 0 ; encoding: [0x80,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], 0 ; encoding: [0x80,0x64,0x00,0x7e] +v_fract_f64_e32 v[0:1], 0 + +// SICI: v_trunc_f32_e64 v0, 0 ; encoding: [0x00,0x00,0x42,0xd3,0x80,0x00,0x00,0x00] +// VI: v_trunc_f32_e64 v0, 0 ; encoding: [0x00,0x00,0x5c,0xd1,0x80,0x00,0x00,0x00] +v_trunc_f32_e64 v0, 0 + +// SICI: v_fract_f64_e64 v[0:1], 0 ; encoding: [0x00,0x00,0x7c,0xd3,0x80,0x00,0x00,0x00] +// VI: v_fract_f64_e64 v[0:1], 0 ; encoding: [0x00,0x00,0x72,0xd1,0x80,0x00,0x00,0x00] +v_fract_f64_e64 v[0:1], 0 + +// SICI: v_trunc_f32_e32 v0, -13 ; encoding: [0xcd,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, -13 ; encoding: [0xcd,0x38,0x00,0x7e] +v_trunc_f32_e32 v0, -13 + +// SICI: v_fract_f64_e32 v[0:1], -13 ; encoding: [0xcd,0x7c,0x00,0x7e] +// 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] +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] +v_fract_f64_e64 v[0:1], -13 + +// SICI: v_trunc_f32_e32 v0, 35 ; encoding: [0xa3,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, 35 ; encoding: [0xa3,0x38,0x00,0x7e] +v_trunc_f32_e32 v0, 35 + +// SICI: v_fract_f64_e32 v[0:1], 35 ; encoding: [0xa3,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], 35 ; encoding: [0xa3,0x64,0x00,0x7e] +v_fract_f64_e32 v[0:1], 35 + +// SICI: v_trunc_f32_e64 v0, 35 ; encoding: [0x00,0x00,0x42,0xd3,0xa3,0x00,0x00,0x00] +// VI: v_trunc_f32_e64 v0, 35 ; encoding: [0x00,0x00,0x5c,0xd1,0xa3,0x00,0x00,0x00] +v_trunc_f32_e64 v0, 35 + +// SICI: v_fract_f64_e64 v[0:1], 35 ; encoding: [0x00,0x00,0x7c,0xd3,0xa3,0x00,0x00,0x00] +// VI: v_fract_f64_e64 v[0:1], 35 ; encoding: [0x00,0x00,0x72,0xd1,0xa3,0x00,0x00,0x00] +v_fract_f64_e64 v[0:1], 35 + +// SICI: v_trunc_f32_e32 v0, 0x4d2 ; encoding: [0xff,0x42,0x00,0x7e,0xd2,0x04,0x00,0x00] +// VI: v_trunc_f32_e32 v0, 0x4d2 ; encoding: [0xff,0x38,0x00,0x7e,0xd2,0x04,0x00,0x00] +v_trunc_f32_e32 v0, 1234 + +// SICI: v_fract_f64_e32 v[0:1], 0x4d2 ; encoding: [0xff,0x7c,0x00,0x7e,0xd2,0x04,0x00,0x00] +// VI: v_fract_f64_e32 v[0:1], 0x4d2 ; encoding: [0xff,0x64,0x00,0x7e,0xd2,0x04,0x00,0x00] +v_fract_f64_e32 v[0:1], 1234 + +// NOSICI: error: Can't encode integer literal. Only inlinable literals are allowed +// NOVI: error: Can't encode integer literal. Only inlinable literals are allowed +v_trunc_f32_e64 v0, 1234 + +// NOSICI: error: Can't encode integer literal. Only inlinable literals are allowed +// NOVI: error: Can't encode integer literal. Only inlinable literals are allowed +v_fract_f64_e64 v[0:1], 1234 + +// SICI: v_trunc_f32_e32 v0, 0xffff2bcf ; encoding: [0xff,0x42,0x00,0x7e,0xcf,0x2b,0xff,0xff] +// VI: v_trunc_f32_e32 v0, 0xffff2bcf ; encoding: [0xff,0x38,0x00,0x7e,0xcf,0x2b,0xff,0xff] +v_trunc_f32_e32 v0, -54321 + +// SICI: v_fract_f64_e32 v[0:1], 0xffff2bcf ; encoding: [0xff,0x7c,0x00,0x7e,0xcf,0x2b,0xff,0xff] +// VI: v_fract_f64_e32 v[0:1], 0xffff2bcf ; encoding: [0xff,0x64,0x00,0x7e,0xcf,0x2b,0xff,0xff] +v_fract_f64_e32 v[0:1], -54321 + +// SICI: v_trunc_f32_e32 v0, 0xdeadbeef ; encoding: [0xff,0x42,0x00,0x7e,0xef,0xbe,0xad,0xde] +// VI: v_trunc_f32_e32 v0, 0xdeadbeef ; encoding: [0xff,0x38,0x00,0x7e,0xef,0xbe,0xad,0xde] +v_trunc_f32_e32 v0, 0xdeadbeef + +// SICI: v_fract_f64_e32 v[0:1], 0xdeadbeef ; encoding: [0xff,0x7c,0x00,0x7e,0xef,0xbe,0xad,0xde] +// VI: v_fract_f64_e32 v[0:1], 0xdeadbeef ; encoding: [0xff,0x64,0x00,0x7e,0xef,0xbe,0xad,0xde] +v_fract_f64_e32 v[0:1], 0xdeadbeef + +// SICI: v_trunc_f32_e32 v0, -1 ; encoding: [0xc1,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, -1 ; encoding: [0xc1,0x38,0x00,0x7e] +v_trunc_f32_e32 v0, 0xffffffff + +// SICI: v_fract_f64_e32 v[0:1], 0xffffffff ; encoding: [0xff,0x7c,0x00,0x7e,0xff,0xff,0xff,0xff] +// VI: v_fract_f64_e32 v[0:1], 0xffffffff ; encoding: [0xff,0x64,0x00,0x7e,0xff,0xff,0xff,0xff] +v_fract_f64_e32 v[0:1], 0xffffffff + +// NOSICI: error: Can't encode literal operand +// NOVI: error: Can't encode literal operand +v_trunc_f32_e32 v0, 0x123456789abcdef0 + +// NOSICI: error: Can't encode literal operand +// NOVI: error: Can't encode literal operand +v_fract_f64_e32 v[0:1], 0x123456789abcdef0 + +// SICI: v_trunc_f32_e32 v0, -1 ; encoding: [0xc1,0x42,0x00,0x7e] +// VI: v_trunc_f32_e32 v0, -1 ; encoding: [0xc1,0x38,0x00,0x7e] +v_trunc_f32_e32 v0, 0xffffffffffffffff + +// SICI: v_fract_f64_e32 v[0:1], -1 ; encoding: [0xc1,0x7c,0x00,0x7e] +// VI: v_fract_f64_e32 v[0:1], -1 ; encoding: [0xc1,0x64,0x00,0x7e] +v_fract_f64_e32 v[0:1], 0xffffffffffffffff + +//---------------------------------------------------------------------------// +// int literal, expected int operand +//---------------------------------------------------------------------------// + +// SICI: s_mov_b64 s[0:1], 0 ; encoding: [0x80,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], 0 ; encoding: [0x80,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], 0 + +// SICI: v_and_b32_e32 v0, 0, v1 ; encoding: [0x80,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, 0, v1 ; encoding: [0x80,0x02,0x00,0x26] +v_and_b32_e32 v0, 0, v1 + +// SICI: v_and_b32_e64 v0, 0, v1 ; encoding: [0x00,0x00,0x36,0xd2,0x80,0x02,0x02,0x00] +// VI: v_and_b32_e64 v0, 0, v1 ; encoding: [0x00,0x00,0x13,0xd1,0x80,0x02,0x02,0x00] +v_and_b32_e64 v0, 0, v1 + +// SICI: s_mov_b64 s[0:1], -13 ; encoding: [0xcd,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], -13 ; encoding: [0xcd,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], -13 + +// SICI: v_and_b32_e32 v0, -13, v1 ; encoding: [0xcd,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, -13, v1 ; encoding: [0xcd,0x02,0x00,0x26] +v_and_b32_e32 v0, -13, v1 + +// SICI: v_and_b32_e64 v0, -13, v1 ; encoding: [0x00,0x00,0x36,0xd2,0xcd,0x02,0x02,0x00] +// VI: v_and_b32_e64 v0, -13, v1 ; encoding: [0x00,0x00,0x13,0xd1,0xcd,0x02,0x02,0x00] +v_and_b32_e64 v0, -13, v1 + +// SICI: s_mov_b64 s[0:1], 35 ; encoding: [0xa3,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], 35 ; encoding: [0xa3,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], 35 + +// SICI: v_and_b32_e32 v0, 35, v1 ; encoding: [0xa3,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, 35, v1 ; encoding: [0xa3,0x02,0x00,0x26] +v_and_b32_e32 v0, 35, v1 + +// SICI: v_and_b32_e64 v0, 35, v1 ; encoding: [0x00,0x00,0x36,0xd2,0xa3,0x02,0x02,0x00] +// VI: v_and_b32_e64 v0, 35, v1 ; encoding: [0x00,0x00,0x13,0xd1,0xa3,0x02,0x02,0x00] +v_and_b32_e64 v0, 35, v1 + +// SICI: s_mov_b64 s[0:1], 0x4d2 ; encoding: [0xff,0x04,0x80,0xbe,0xd2,0x04,0x00,0x00] +// VI: s_mov_b64 s[0:1], 0x4d2 ; encoding: [0xff,0x01,0x80,0xbe,0xd2,0x04,0x00,0x00] +s_mov_b64_e32 s[0:1], 1234 + +// SICI: v_and_b32_e32 v0, 0x4d2, v1 ; encoding: [0xff,0x02,0x00,0x36,0xd2,0x04,0x00,0x00] +// VI: v_and_b32_e32 v0, 0x4d2, v1 ; encoding: [0xff,0x02,0x00,0x26,0xd2,0x04,0x00,0x00] +v_and_b32_e32 v0, 1234, v1 + +// NOSICI: error: Can't encode integer literal. Only inlinable literals are allowed +// NOVI: error: Can't encode integer literal. Only inlinable literals are allowed +v_and_b32_e64 v0, 1234, v1 + +// SICI: s_mov_b64 s[0:1], 0xffff2bcf ; encoding: [0xff,0x04,0x80,0xbe,0xcf,0x2b,0xff,0xff] +// VI: s_mov_b64 s[0:1], 0xffff2bcf ; encoding: [0xff,0x01,0x80,0xbe,0xcf,0x2b,0xff,0xff] +s_mov_b64_e32 s[0:1], -54321 + +// SICI: v_and_b32_e32 v0, 0xffff2bcf, v1 ; encoding: [0xff,0x02,0x00,0x36,0xcf,0x2b,0xff,0xff] +// VI: v_and_b32_e32 v0, 0xffff2bcf, v1 ; encoding: [0xff,0x02,0x00,0x26,0xcf,0x2b,0xff,0xff] +v_and_b32_e32 v0, -54321, v1 + +// SICI: s_mov_b64 s[0:1], 0xdeadbeef ; encoding: [0xff,0x04,0x80,0xbe,0xef,0xbe,0xad,0xde] +// VI: s_mov_b64 s[0:1], 0xdeadbeef ; encoding: [0xff,0x01,0x80,0xbe,0xef,0xbe,0xad,0xde] +s_mov_b64_e32 s[0:1], 0xdeadbeef + +// SICI: v_and_b32_e32 v0, 0xdeadbeef, v1 ; encoding: [0xff,0x02,0x00,0x36,0xef,0xbe,0xad,0xde] +// VI: v_and_b32_e32 v0, 0xdeadbeef, v1 ; encoding: [0xff,0x02,0x00,0x26,0xef,0xbe,0xad,0xde] +v_and_b32_e32 v0, 0xdeadbeef, v1 + +// SICI: s_mov_b64 s[0:1], 0xffffffff ; encoding: [0xff,0x04,0x80,0xbe,0xff,0xff,0xff,0xff] +// VI: s_mov_b64 s[0:1], 0xffffffff ; encoding: [0xff,0x01,0x80,0xbe,0xff,0xff,0xff,0xff] +s_mov_b64_e32 s[0:1], 0xffffffff + +// SICI: v_and_b32_e32 v0, -1, v1 ; encoding: [0xc1,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, -1, v1 ; encoding: [0xc1,0x02,0x00,0x26] +v_and_b32_e32 v0, 0xffffffff, v1 + +// NOSICI: error: Can't encode literal operand +// NOVI: error: Can't encode literal operand +s_mov_b64_e32 s[0:1], 0x123456789abcdef0 + +// NOSICI: error: Can't encode literal operand +// NOVI: error: Can't encode literal operand +v_and_b32_e32 v0, 0x123456789abcdef0, v1 + +// SICI: s_mov_b64 s[0:1], -1 ; encoding: [0xc1,0x04,0x80,0xbe] +// VI: s_mov_b64 s[0:1], -1 ; encoding: [0xc1,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], 0xffffffffffffffff + +// SICI: v_and_b32_e32 v0, -1, v1 ; encoding: [0xc1,0x02,0x00,0x36] +// VI: v_and_b32_e32 v0, -1, v1 ; encoding: [0xc1,0x02,0x00,0x26] +v_and_b32_e32 v0, 0xffffffffffffffff, v1 + +//---------------------------------------------------------------------------// +// 1/(2*PI) +//---------------------------------------------------------------------------// + +// NOSICI: error: Can't encode literal operand +// NOVI: error: Can't encode literal operand +v_trunc_f32_e32 v0, 0x3fc45f306dc9c882 + +// NOSICI: error: Can't encode literal operand +// VI: v_fract_f64_e32 v[0:1], 0x3fc45f306dc9c882 ; encoding: [0xf8,0x64,0x00,0x7e] +v_fract_f64_e32 v[0:1], 0x3fc45f306dc9c882 + +// SICI: v_trunc_f32_e32 v0, 0x3e22f983 ; encoding: [0xff,0x42,0x00,0x7e,0x83,0xf9,0x22,0x3e] +// VI: v_trunc_f32_e32 v0, 0x3e22f983 ; encoding: [0xf8,0x38,0x00,0x7e] +v_trunc_f32_e32 v0, 0x3e22f983 + +// SICI: v_fract_f64_e32 v[0:1], 0x3e22f983 ; encoding: [0xff,0x7c,0x00,0x7e,0x83,0xf9,0x22,0x3e] +// VI: v_fract_f64_e32 v[0:1], 0x3e22f983 ; encoding: [0xff,0x64,0x00,0x7e,0x83,0xf9,0x22,0x3e] +v_fract_f64_e32 v[0:1], 0x3e22f983 + +// NOSICI: error: Can't encode integer literal. Only inlinable literals are allowed +// NOVI: error: Can't encode integer literal. Only inlinable literals are allowed +v_trunc_f32_e64 v0, 0x3fc45f306dc9c882 + +// NOSICI: error: Can't encode integer literal. Only inlinable literals are allowed +// VI: v_fract_f64_e64 v[0:1], 0x3fc45f306dc9c882 ; encoding: [0x00,0x00,0x72,0xd1,0xf8,0x00,0x00,0x00] +v_fract_f64_e64 v[0:1], 0x3fc45f306dc9c882 + +// NOSICI: error: Can't encode integer literal. Only inlinable literals are allowed +// NOVI: error: Can't encode integer literal. Only inlinable literals are allowed +v_trunc_f32_e64 v0, 0x3e22f983 + +// NOSICI: error: Can't encode integer literal. Only inlinable literals are allowed +// VI: v_trunc_f32_e64 v0, 0x3e22f983 ; encoding: [0x00,0x00,0x5c,0xd1,0xf8,0x00,0x00,0x00] +v_fract_f64_e64 v[0:1], 0x3e22f983 + +// NOSICI: error: Can't encode floating-point literal as 64-bit integer operand. Only inlinable floating-point literals are allowed +// VI: s_mov_b64 s[0:1], 0x3fc45f306dc9c882 ; encoding: [0xf8,0x01,0x80,0xbe] +s_mov_b64_e32 s[0:1], 0.159154943091895317852646485335 + +// SICI: v_and_b32_e32 v0, 0x3e22f983, v1 ; encoding: [0xff,0x02,0x00,0x36,0x83,0xf9,0x22,0x3e] +// VI: v_and_b32_e32 v0, 0x3e22f983, v1 ; encoding: [0xf8,0x02,0x00,0x26] +v_and_b32_e32 v0, 0.159154943091895317852646485335, v1 + +// NOSICI: error: Can't encode floating-point literal. Only inlinable literals are allowed +// VI: v_and_b32_e64 v0, 0x3e22f983, v1 ; encoding: [0x00,0x00,0x13,0xd1,0xf8,0x02,0x02,0x00] +v_and_b32_e64 v0, 0.159154943091895317852646485335, v1 + +// NOSICI: warning: Can't encode literal as exact 64-bit floating-point operand. Low 32-bits will be set to zero +// SICI: v_fract_f64_e32 v[0:1], 0x3fc45f30 ; encoding: [0xff,0x7c,0x00,0x7e,0x30,0x5f,0xc4,0x3f] +// VI: v_fract_f64_e32 v[0:1], 0x3fc45f306dc9c882 ; encoding: [0xf8,0x64,0x00,0x7e] +v_fract_f64 v[0:1], 0.159154943091895317852646485335 + +// SICI: v_trunc_f32_e32 v0, 0x3e22f983 ; encoding: [0xff,0x42,0x00,0x7e,0x83,0xf9,0x22,0x3e] +// VI: v_trunc_f32_e32 v0, 0x3e22f983 ; encoding: [0xf8,0x38,0x00,0x7e] +v_trunc_f32 v0, 0.159154943091895317852646485335 \ No newline at end of file