Index: lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -330,6 +330,15 @@ MCAsmParser &Parser; unsigned ForcedEncodingSize; + + bool isVI() const { + return STI.getFeatureBits()[AMDGPU::FeatureVolcanicIslands]; + } + + bool hasSGPR102_SGPR103() const { + return !isVI(); + } + /// @name Auto-generated Match Functions /// { @@ -345,6 +354,7 @@ bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header); bool ParseDirectiveAMDKernelCodeT(); bool ParseSectionDirectiveHSAText(); + bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const; public: public: @@ -356,7 +366,7 @@ const MCInstrInfo &MII, const MCTargetOptions &Options) : MCTargetAsmParser(Options), STI(STI), MII(MII), Parser(_Parser), - ForcedEncodingSize(0){ + ForcedEncodingSize(0) { if (STI.getFeatureBits().none()) { // Set default features. @@ -559,7 +569,7 @@ return true; RegNo = RC.getRegister(RegIndexInClass); - return false; + return !subtargetHasRegister(*TRI, RegNo); } unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) { @@ -950,6 +960,22 @@ return true; } +bool AMDGPUAsmParser::subtargetHasRegister(const MCRegisterInfo &MRI, + unsigned RegNo) const { + if (!isVI()) + return true; + + // VI only has 102 SGPRs, so make sure we aren't trying to use the 2 more that + // SI/CI have. + for (MCRegAliasIterator R(AMDGPU::SGPR102_SGPR103, &MRI, true); + R.isValid(); ++R) { + if (*R == RegNo) + return false; + } + + return true; +} + static bool operandsHaveModifiers(const OperandVector &Operands) { for (unsigned i = 0, e = Operands.size(); i != e; ++i) { Index: test/MC/AMDGPU/smrd-err.s =================================================================== --- /dev/null +++ test/MC/AMDGPU/smrd-err.s @@ -0,0 +1,15 @@ +// RUN: llvm-mc -arch=amdgcn -mcpu=tahiti %s | FileCheck -check-prefix=GCN -check-prefix=SI %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=VI %s + +s_load_dwordx4 s[100:103], s[2:3], s4 +// VI: error: invalid operand for instruction +// SI: s_load_dwordx4 s[100:103], s[2:3], s4 + + +s_load_dwordx8 s[96:103], s[2:3], s4 +// VI: error: invalid operand for instruction +// SI: s_load_dwordx8 s[96:103], s[2:3], s4 + +s_load_dwordx16 s[88:103], s[2:3], s4 +// VI: error: invalid operand for instruction +// SI: s_load_dwordx16 s[88:103], s[2:3], s4 Index: test/MC/AMDGPU/sop1-err.s =================================================================== --- test/MC/AMDGPU/sop1-err.s +++ test/MC/AMDGPU/sop1-err.s @@ -1,46 +1,59 @@ -// RUN: not llvm-mc -arch=amdgcn %s 2>&1 | FileCheck %s -// RUN: not llvm-mc -arch=amdgcn -mcpu=SI %s 2>&1 | FileCheck %s +// RUN: not llvm-mc -arch=amdgcn %s 2>&1 | FileCheck -check-prefix=GCN %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=SI %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=VI %s s_mov_b32 v1, s2 -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction s_mov_b32 s1, v0 -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction s_mov_b32 s[1:2], s0 -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction s_mov_b32 s0, s[1:2] -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction s_mov_b32 s220, s0 -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction s_mov_b32 s0, s220 -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction s_mov_b64 s1, s[0:1] -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction s_mov_b64 s[0:1], s1 -// CHECK: error: invalid operand for instruction +// GCN: error: invalid operand for instruction // Immediate greater than 32-bits s_mov_b32 s1, 0xfffffffff -// CHECK: error: invalid immediate: only 32-bit values are legal +// GCN: error: invalid immediate: only 32-bit values are legal // Immediate greater than 32-bits s_mov_b64 s[0:1], 0xfffffffff -// CHECK: error: invalid immediate: only 32-bit values are legal +// GCN: error: invalid immediate: only 32-bit values are legal s_mov_b64 s[0:1], 0xfffffffff -// CHECK: error: invalid immediate: only 32-bit values are legal +// GCN: error: invalid immediate: only 32-bit values are legal s_mov_b64 s[0:1], 0xfffffffff -// CHECK: error: invalid immediate: only 32-bit values are legal +// GCN: error: invalid immediate: only 32-bit values are legal s_mov_b64 s[0:1], 0x0000000200000000 -// CHECK: error: invalid immediate: only 32-bit values are legal +// GCN: error: invalid immediate: only 32-bit values are legal // Out of range register s_mov_b32 s + +s_mov_b32 s102, 1 +// VI: error: invalid operand for instruction +// SI-NOT: error + +s_mov_b32 s103, 1 +// VI: error: invalid operand for instruction +// SI-NOT: error + +s_mov_b64 s[102:103], -1 +// VI: error: invalid operand for instruction +// SI-NOT: error