Skip to content

[SystemZ] Implement .machine (push|pop) directives #137302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/TargetParser/SubtargetFeature.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
Expand Down Expand Up @@ -410,6 +411,12 @@ class SystemZAsmParser : public MCTargetAsmParser {

private:
MCAsmParser &Parser;

// A vector to contain the stack of FeatureBitsets created by `.machine push`.
// `.machine pop` pops the top of the stack and uses `setAvailableFeatures` to
// apply the result.
SmallVector<FeatureBitset> MachineStack;

enum RegisterGroup {
RegGR,
RegFP,
Expand Down Expand Up @@ -494,9 +501,8 @@ class SystemZAsmParser : public MCTargetAsmParser {

public:
SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
const MCInstrInfo &MII,
const MCTargetOptions &Options)
: MCTargetAsmParser(Options, sti, MII), Parser(parser) {
const MCInstrInfo &MII, const MCTargetOptions &Options)
: MCTargetAsmParser(Options, sti, MII), Parser(parser) {
MCAsmParserExtension::Initialize(Parser);

// Alias the .word directive to .short.
Expand Down Expand Up @@ -1382,16 +1388,32 @@ bool SystemZAsmParser::parseDirectiveMachine(SMLoc L) {
Parser.getTok().isNot(AsmToken::String))
return TokError("unexpected token in '.machine' directive");

StringRef CPU = Parser.getTok().getIdentifier();
StringRef Id = Parser.getTok().getIdentifier();
SMLoc IdLoc = Parser.getTok().getLoc();

Parser.Lex();
if (parseEOL())
return true;

MCSubtargetInfo &STI = copySTI();
STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));

getTargetStreamer().emitMachine(CPU);
// Parse push and pop directives first
if (Id == "push") {
// Push the Current FeatureBitSet onto the stack.
MachineStack.push_back(getAvailableFeatures());
} else if (Id == "pop") {
// If the stack is not empty pop the topmost FeatureBitset and use it.
if (MachineStack.empty())
return Error(IdLoc,
"pop without corresponding push in '.machine' directive");
setAvailableFeatures(MachineStack.back());
MachineStack.pop_back();
} else {
// Try to interpret the Identifier as a CPU spec and derive the
// FeatureBitset from that.
MCSubtargetInfo &STI = copySTI();
STI.setDefaultFeatures(Id, /*TuneCPU*/ Id, "");
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
}
getTargetStreamer().emitMachine(Id);

return false;
}
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SystemZTargetStreamer : public MCTargetStreamer {

void emitConstantPools() override;

virtual void emitMachine(StringRef CPU) {};
virtual void emitMachine(StringRef CPUOrCommand) {};

virtual void emitExtern(StringRef Str) {};

Expand Down Expand Up @@ -85,7 +85,7 @@ class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
class SystemZTargetELFStreamer : public SystemZTargetStreamer {
public:
SystemZTargetELFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
void emitMachine(StringRef CPU) override {}
void emitMachine(StringRef CPUOrCommand) override {}
};

class SystemZTargetGNUStreamer : public SystemZTargetStreamer {
Expand All @@ -94,8 +94,8 @@ class SystemZTargetGNUStreamer : public SystemZTargetStreamer {
public:
SystemZTargetGNUStreamer(MCStreamer &S, formatted_raw_ostream &OS)
: SystemZTargetStreamer(S), OS(OS) {}
void emitMachine(StringRef CPU) override {
OS << "\t.machine " << CPU << "\n";
void emitMachine(StringRef CPUOrCommand) override {
OS << "\t.machine " << CPUOrCommand << "\n";
}
};

Expand Down
13 changes: 10 additions & 3 deletions llvm/test/MC/SystemZ/machine-directive-invalid.s
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
# RUN: not llvm-mc -triple=s390x %s 2>&1 | FileCheck %s

# CHECK: [[#@LINE+1]]:9: error: unexpected token in '.machine' directive
.machine
// CHECK: :[[@LINE-1]]:9: error: unexpected token in '.machine' directive

.machine pop
// CHECK: :[[@LINE-1]]:10: error: pop without corresponding push in '.machine' directive

.machine pop z13
// CHECK: :[[@LINE-1]]:14: error: expected newline

# CHECK: [[#@LINE+1]]:10: error: unexpected token in '.machine' directive
.machine 42
// CHECK: :[[@LINE-1]]:10: error: unexpected token in '.machine' directive

# CHECK: [[#@LINE+1]]:13: error: expected newline
.machine z13+
// CHECK: :[[@LINE-1]]:13: error: expected newline
10 changes: 7 additions & 3 deletions llvm/test/MC/SystemZ/machine-directive.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@
# CHECK: ^
# CHECK-NOT: error:
# CHECK: .machine push
# CHECK: .machine z13
# CHECK: vgbm %v0, 0
# CHECK: .machine zEC12
# CHECK: .machine z13
# CHECK: .machine pop
# CHECK: vgbm %v0, 3
# CHECK: .machine pop

.machine push
.machine z13
.machine push
vgbm %v0, 0
.machine zEC12
vgbm %v0, 1
.machine z13
.machine pop
vgbm %v0, 3

.machine pop
Loading