Index: lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp +++ lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp @@ -162,20 +162,30 @@ uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO, unsigned OpSize) const { - if (MO.isExpr()) - return 255; - assert(!MO.isFPImm()); + int64_t Imm; + if (MO.isExpr()) { + const MCConstantExpr *C = dyn_cast(MO.getExpr()); + if (!C) + return 255; + + Imm = C->getValue(); + } else { - if (!MO.isImm()) - return ~0; + assert(!MO.isFPImm()); + + if (!MO.isImm()) + return ~0; + + Imm = MO.getImm(); + } if (OpSize == 4) - return getLit32Encoding(static_cast(MO.getImm())); + return getLit32Encoding(static_cast(Imm)); assert(OpSize == 8); - return getLit64Encoding(static_cast(MO.getImm())); + return getLit64Encoding(static_cast(Imm)); } void SIMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, @@ -213,7 +223,11 @@ if (Op.isImm()) Imm = Op.getImm(); - else if (!Op.isExpr()) // Exprs will be replaced with a fixup value. + else if (Op.isExpr()) { + if (const MCConstantExpr *C = dyn_cast(Op.getExpr())) + Imm = C->getValue(); + + } else if (!Op.isExpr()) // Exprs will be replaced with a fixup value. llvm_unreachable("Must be immediate or expr"); for (unsigned j = 0; j < 4; j++) { @@ -247,7 +261,7 @@ if (MO.isReg()) return MRI.getEncodingValue(MO.getReg()); - if (MO.isExpr()) { + if (MO.isExpr() && MO.getExpr()->getKind() != MCExpr::Constant) { const MCSymbolRefExpr *Expr = dyn_cast(MO.getExpr()); MCFixupKind Kind; if (Expr && Expr->getSymbol().isExternal()) Index: test/MC/AMDGPU/expressions.s =================================================================== --- test/MC/AMDGPU/expressions.s +++ test/MC/AMDGPU/expressions.s @@ -29,3 +29,13 @@ s_addc_u32 s1, s1, 0 // VI: s_add_u32 s0, s0, global+4 // VI: s_addc_u32 s1, s1, 0 + +// Use a computed expression that results in an inline immediate. +.set foo, 4 +s_mov_b32 s0, foo+2 +// VI: s_mov_b32 s0, 6 ; encoding: [0x86,0x00,0x80,0xbe] + +// Use a computed expression that results in a non-inline immediate. +.set foo, 512 +s_mov_b32 s0, foo+2 +// VI: s_mov_b32 s0, 514 ; encoding: [0xff,0x00,0x80,0xbe,0x02,0x02,0x00,0x00]