mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 07:09:08 +00:00
AMDGPU/SI: Correctly encode constant expressions
Summary: We we have an MCConstantExpr, we can encode it directly into the instruction instead of emitting fixups. Reviewers: artem.tamazov, vpykhtin, SamWot, nhaustov, arsenm Subscribers: arsenm, llvm-commits, kzhuravl Differential Revision: http://reviews.llvm.org/D21236 Change-Id: I88b3edf288d48e65c5d705fc4850d281f8e36948 llvm-svn: 272750
This commit is contained in:
parent
b2b24199c2
commit
086f34224b
@ -162,20 +162,30 @@ static uint32_t getLit64Encoding(uint64_t Val) {
|
||||
|
||||
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<MCConstantExpr>(MO.getExpr());
|
||||
if (!C)
|
||||
return 255;
|
||||
|
||||
if (!MO.isImm())
|
||||
return ~0;
|
||||
Imm = C->getValue();
|
||||
} else {
|
||||
|
||||
assert(!MO.isFPImm());
|
||||
|
||||
if (!MO.isImm())
|
||||
return ~0;
|
||||
|
||||
Imm = MO.getImm();
|
||||
}
|
||||
|
||||
if (OpSize == 4)
|
||||
return getLit32Encoding(static_cast<uint32_t>(MO.getImm()));
|
||||
return getLit32Encoding(static_cast<uint32_t>(Imm));
|
||||
|
||||
assert(OpSize == 8);
|
||||
|
||||
return getLit64Encoding(static_cast<uint64_t>(MO.getImm()));
|
||||
return getLit64Encoding(static_cast<uint64_t>(Imm));
|
||||
}
|
||||
|
||||
void SIMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
@ -213,7 +223,11 @@ void SIMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
|
||||
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<MCConstantExpr>(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 @@ uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI,
|
||||
if (MO.isReg())
|
||||
return MRI.getEncodingValue(MO.getReg());
|
||||
|
||||
if (MO.isExpr()) {
|
||||
if (MO.isExpr() && MO.getExpr()->getKind() != MCExpr::Constant) {
|
||||
const MCSymbolRefExpr *Expr = dyn_cast<MCSymbolRefExpr>(MO.getExpr());
|
||||
MCFixupKind Kind;
|
||||
if (Expr && Expr->getSymbol().isExternal())
|
||||
|
@ -29,3 +29,13 @@ s_add_u32 s0, s0, global+4
|
||||
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]
|
||||
|
Loading…
Reference in New Issue
Block a user