Lanai: Migrate to the new relocation specifier representation

Use MCSpecifierExpr directly and remove the LanaiMCExpr subclass. Define
MCSpecifierExpr::printImpl to print the relocation specifier in decimal
for llvm-mc -show-inst. The output is not guaranteed to be stable.

Depends on f8e0518120
("MC: Adjust -show-inst output for MCExpr")
This commit is contained in:
Fangrui Song
2025-06-15 21:50:48 -07:00
parent f8e0518120
commit 05a9ad9776
8 changed files with 95 additions and 147 deletions

View File

@@ -9,7 +9,7 @@
#include "LanaiAluCode.h"
#include "LanaiCondCode.h"
#include "LanaiInstrInfo.h"
#include "MCTargetDesc/LanaiMCExpr.h"
#include "MCTargetDesc/LanaiMCAsmInfo.h"
#include "TargetInfo/LanaiTargetInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
@@ -231,14 +231,14 @@ public:
}
// Symbolic reference expression
if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_HI;
if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_HI;
// Binary expression
if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
if (const LanaiMCExpr *SymbolRefExpr =
dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_HI;
if (const auto *SymbolRefExpr =
dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_HI;
return false;
}
@@ -268,14 +268,14 @@ public:
}
// Symbolic reference expression
if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_LO;
if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
// Binary expression
if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
if (const LanaiMCExpr *SymbolRefExpr =
dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_LO;
if (const auto *SymbolRefExpr =
dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
return false;
}
@@ -292,14 +292,14 @@ public:
}
// Symbolic reference expression
if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_LO;
if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
// Binary expression
if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
if (const LanaiMCExpr *SymbolRefExpr =
dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_LO;
if (const auto *SymbolRefExpr =
dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO;
return false;
}
@@ -339,8 +339,8 @@ public:
}
// Symbolic reference expression
if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_None;
if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Imm.Value))
return SymbolRefExpr->getSpecifier() == Lanai::S_None;
if (const MCSymbolRefExpr *SymbolRefExpr =
dyn_cast<MCSymbolRefExpr>(Imm.Value)) {
return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
@@ -348,9 +348,9 @@ public:
// Binary expression
if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
if (const LanaiMCExpr *SymbolRefExpr =
dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_None;
if (const auto *SymbolRefExpr =
dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getSpecifier() == Lanai::S_None;
if (const MCSymbolRefExpr *SymbolRefExpr =
dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
@@ -464,19 +464,18 @@ public:
if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
Inst.addOperand(
MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
else if (isa<LanaiMCExpr>(getImm())) {
else if (isa<MCSpecifierExpr>(getImm())) {
#ifndef NDEBUG
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
assert(SymbolRefExpr &&
SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_LO);
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(getImm());
assert(SymbolRefExpr && SymbolRefExpr->getSpecifier() == Lanai::S_ABS_LO);
#endif
Inst.addOperand(MCOperand::createExpr(getImm()));
} else if (isa<MCBinaryExpr>(getImm())) {
#ifndef NDEBUG
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
cast<LanaiMCExpr>(BinaryExpr->getLHS())->getSpecifier() ==
LanaiMCExpr::VK_Lanai_ABS_LO);
assert(BinaryExpr && isa<MCSpecifierExpr>(BinaryExpr->getLHS()) &&
cast<MCSpecifierExpr>(BinaryExpr->getLHS())->getSpecifier() ==
Lanai::S_ABS_LO);
#endif
Inst.addOperand(MCOperand::createExpr(getImm()));
} else
@@ -495,19 +494,18 @@ public:
assert(N == 1 && "Invalid number of operands!");
if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
else if (isa<LanaiMCExpr>(getImm())) {
else if (isa<MCSpecifierExpr>(getImm())) {
#ifndef NDEBUG
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
assert(SymbolRefExpr &&
SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_ABS_HI);
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(getImm());
assert(SymbolRefExpr && SymbolRefExpr->getSpecifier() == Lanai::S_ABS_HI);
#endif
Inst.addOperand(MCOperand::createExpr(getImm()));
} else if (isa<MCBinaryExpr>(getImm())) {
#ifndef NDEBUG
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
cast<LanaiMCExpr>(BinaryExpr->getLHS())->getSpecifier() ==
LanaiMCExpr::VK_Lanai_ABS_HI);
assert(BinaryExpr && isa<MCSpecifierExpr>(BinaryExpr->getLHS()) &&
cast<MCSpecifierExpr>(BinaryExpr->getLHS())->getSpecifier() ==
Lanai::S_ABS_HI);
#endif
Inst.addOperand(MCOperand::createExpr(getImm()));
} else
@@ -526,11 +524,10 @@ public:
assert(N == 1 && "Invalid number of operands!");
if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
else if (isa<LanaiMCExpr>(getImm())) {
else if (isa<MCSpecifierExpr>(getImm())) {
#ifndef NDEBUG
const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
assert(SymbolRefExpr &&
SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_None);
const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(getImm());
assert(SymbolRefExpr && SymbolRefExpr->getSpecifier() == Lanai::S_None);
#endif
Inst.addOperand(MCOperand::createExpr(getImm()));
} else if (isa<MCSymbolRefExpr>(getImm())) {
@@ -544,9 +541,9 @@ public:
} else if (isa<MCBinaryExpr>(getImm())) {
#ifndef NDEBUG
const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
cast<LanaiMCExpr>(BinaryExpr->getLHS())->getSpecifier() ==
LanaiMCExpr::VK_Lanai_None);
assert(BinaryExpr && isa<MCSpecifierExpr>(BinaryExpr->getLHS()) &&
cast<MCSpecifierExpr>(BinaryExpr->getLHS())->getSpecifier() ==
Lanai::S_None);
#endif
Inst.addOperand(MCOperand::createExpr(getImm()));
} else
@@ -737,7 +734,7 @@ std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
SMLoc Start = Parser.getTok().getLoc();
SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
const MCExpr *Res, *RHS = nullptr;
LanaiMCExpr::Spec Kind = LanaiMCExpr::VK_Lanai_None;
auto Kind = Lanai::S_None;
if (Lexer.getKind() != AsmToken::Identifier)
return nullptr;
@@ -748,13 +745,13 @@ std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
// Check if identifier has a modifier
if (Identifier.equals_insensitive("hi"))
Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
Kind = Lanai::S_ABS_HI;
else if (Identifier.equals_insensitive("lo"))
Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
Kind = Lanai::S_ABS_LO;
// If the identifier corresponds to a variant then extract the real
// identifier.
if (Kind != LanaiMCExpr::VK_Lanai_None) {
if (Kind != Lanai::S_None) {
if (Lexer.getKind() != AsmToken::LParen) {
Error(Lexer.getLoc(), "Expected '('");
return nullptr;
@@ -771,7 +768,7 @@ std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
return nullptr;
// For variants parse the final ')'
if (Kind != LanaiMCExpr::VK_Lanai_None) {
if (Kind != Lanai::S_None) {
if (Lexer.getKind() != AsmToken::RParen) {
Error(Lexer.getLoc(), "Expected ')'");
return nullptr;
@@ -781,8 +778,7 @@ std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
Res = LanaiMCExpr::create(Kind, Expr, getContext());
Res = MCSpecifierExpr::create(Sym, Kind, getContext());
// Nest if this was an addition
if (RHS)
@@ -865,16 +861,16 @@ bool shouldBeSls(const LanaiOperand &Op) {
}
// The instruction should be encoded as an SLS if the operand is a symbolic
// reference with no variant.
if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
return SymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_None;
if (const auto *SymbolRefExpr = dyn_cast<MCSpecifierExpr>(Op.getImm()))
return SymbolRefExpr->getSpecifier() == Lanai::S_None;
// The instruction should be encoded as an SLS if the operand is a binary
// expression with the left-hand side being a symbolic reference with no
// variant.
if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
const LanaiMCExpr *LHSSymbolRefExpr =
dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
const auto *LHSSymbolRefExpr =
dyn_cast<MCSpecifierExpr>(BinaryExpr->getLHS());
return (LHSSymbolRefExpr &&
LHSSymbolRefExpr->getSpecifier() == LanaiMCExpr::VK_Lanai_None);
LHSSymbolRefExpr->getSpecifier() == Lanai::S_None);
}
return false;
}

View File

@@ -14,7 +14,7 @@
#include "LanaiMCInstLower.h"
#include "MCTargetDesc/LanaiBaseInfo.h"
#include "MCTargetDesc/LanaiMCExpr.h"
#include "MCTargetDesc/LanaiMCAsmInfo.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -64,17 +64,16 @@ LanaiMCInstLower::GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
MCOperand LanaiMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const {
LanaiMCExpr::Spec Kind;
Lanai::Specifier Kind;
switch (MO.getTargetFlags()) {
case LanaiII::MO_NO_FLAG:
Kind = LanaiMCExpr::VK_Lanai_None;
Kind = Lanai::S_None;
break;
case LanaiII::MO_ABS_HI:
Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
Kind = Lanai::S_ABS_HI;
break;
case LanaiII::MO_ABS_LO:
Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
Kind = Lanai::S_ABS_LO;
break;
default:
llvm_unreachable("Unknown target flag on GV operand");
@@ -84,7 +83,7 @@ MCOperand LanaiMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
if (!MO.isJTI() && MO.getOffset())
Expr = MCBinaryExpr::createAdd(
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
Expr = LanaiMCExpr::create(Kind, Expr, Ctx);
Expr = MCSpecifierExpr::create(Expr, Kind, Ctx);
return MCOperand::createExpr(Expr);
}

View File

@@ -4,7 +4,6 @@ add_llvm_component_library(LLVMLanaiDesc
LanaiInstPrinter.cpp
LanaiMCAsmInfo.cpp
LanaiMCCodeEmitter.cpp
LanaiMCExpr.cpp
LanaiMCTargetDesc.cpp
LINK_COMPONENTS

View File

@@ -11,7 +11,8 @@
//===----------------------------------------------------------------------===//
#include "LanaiMCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
using namespace llvm;
@@ -38,3 +39,26 @@ LanaiMCAsmInfo::LanaiMCAsmInfo(const Triple & /*TheTriple*/,
// in dwarf generation.
MinInstAlignment = 4;
}
void LanaiMCAsmInfo::printSpecifierExpr(raw_ostream &OS,
const MCSpecifierExpr &Expr) const {
if (Expr.getSpecifier() == 0) {
printExpr(OS, *Expr.getSubExpr());
return;
}
switch (Expr.getSpecifier()) {
default:
llvm_unreachable("Invalid kind!");
case Lanai::S_ABS_HI:
OS << "hi";
break;
case Lanai::S_ABS_LO:
OS << "lo";
break;
}
OS << '(';
printExpr(OS, *Expr.getSubExpr());
OS << ')';
}

View File

@@ -24,8 +24,15 @@ class LanaiMCAsmInfo : public MCAsmInfoELF {
public:
explicit LanaiMCAsmInfo(const Triple &TheTriple,
const MCTargetOptions &Options);
void printSpecifierExpr(raw_ostream &OS,
const MCSpecifierExpr &Expr) const override;
};
namespace Lanai {
using Specifier = uint8_t;
enum { S_None, S_ABS_HI, S_ABS_LO };
} // namespace Lanai
} // namespace llvm
#endif // LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCASMINFO_H

View File

@@ -13,7 +13,7 @@
#include "LanaiAluCode.h"
#include "MCTargetDesc/LanaiBaseInfo.h"
#include "MCTargetDesc/LanaiFixupKinds.h"
#include "MCTargetDesc/LanaiMCExpr.h"
#include "MCTargetDesc/LanaiMCAsmInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/MC/MCCodeEmitter.h"
@@ -89,14 +89,14 @@ public:
static Lanai::Fixups FixupKind(const MCExpr *Expr) {
if (isa<MCSymbolRefExpr>(Expr))
return Lanai::FIXUP_LANAI_21;
if (const LanaiMCExpr *McExpr = dyn_cast<LanaiMCExpr>(Expr)) {
LanaiMCExpr::Spec ExprKind = McExpr->getSpecifier();
if (const MCSpecifierExpr *McExpr = dyn_cast<MCSpecifierExpr>(Expr)) {
Lanai::Specifier ExprKind = McExpr->getSpecifier();
switch (ExprKind) {
case LanaiMCExpr::VK_Lanai_None:
case Lanai::S_None:
return Lanai::FIXUP_LANAI_21;
case LanaiMCExpr::VK_Lanai_ABS_HI:
case Lanai::S_ABS_HI:
return Lanai::FIXUP_LANAI_HI16;
case LanaiMCExpr::VK_Lanai_ABS_LO:
case Lanai::S_ABS_LO:
return Lanai::FIXUP_LANAI_LO16;
}
}
@@ -123,7 +123,7 @@ unsigned LanaiMCCodeEmitter::getMachineOpValue(
Expr = BinaryExpr->getLHS();
}
assert(isa<LanaiMCExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef);
assert(isa<MCSpecifierExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef);
// Push fixup (all info is contained within)
Fixups.push_back(
MCFixup::create(0, MCOp.getExpr(), MCFixupKind(FixupKind(Expr))));

View File

@@ -1,44 +0,0 @@
//===-- LanaiMCExpr.cpp - Lanai specific MC expression classes ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "LanaiMCExpr.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
#define DEBUG_TYPE "lanaimcexpr"
const LanaiMCExpr *LanaiMCExpr::create(Spec S, const MCExpr *Expr,
MCContext &Ctx) {
return new (Ctx) LanaiMCExpr(Expr, S);
}
void LanaiMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
if (specifier == VK_Lanai_None) {
MAI->printExpr(OS, *Expr);
return;
}
switch (specifier) {
default:
llvm_unreachable("Invalid kind!");
case VK_Lanai_ABS_HI:
OS << "hi";
break;
case VK_Lanai_ABS_LO:
OS << "lo";
break;
}
OS << '(';
const MCExpr *Expr = getSubExpr();
MAI->printExpr(OS, *Expr);
OS << ')';
}

View File

@@ -1,33 +0,0 @@
//===-- LanaiMCExpr.h - Lanai specific MC expression classes ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCEXPR_H
#define LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCEXPR_H
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCValue.h"
namespace llvm {
class LanaiMCExpr : public MCSpecifierExpr {
public:
using Spec = MCSpecifierExpr::Spec;
enum { VK_Lanai_None, VK_Lanai_ABS_HI, VK_Lanai_ABS_LO };
private:
explicit LanaiMCExpr(const MCExpr *Expr, Spec S) : MCSpecifierExpr(Expr, S) {}
public:
static const LanaiMCExpr *create(Spec Kind, const MCExpr *Expr,
MCContext &Ctx);
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
};
} // end namespace llvm
#endif