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

Dominik Steenken via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 25 02:47:43 PDT 2025


https://github.com/dominik-steenken created https://github.com/llvm/llvm-project/pull/137302

The `.machine push` and `.machine pop` directives were missing from the SystemZ Backend Asm Parser. This PR adds them, and expands the corresponding test to test proper operation.

Internally, this is modeled as a simple stack implemented on a `SmallVector<StringRef>`.

This implementation makes the assumption that, without any `.machine` directive, the "current" machine is undefined, rather than trying to derive it based on the host machine. Thus, in this implementation, any `.machine push` *must* be preceded by at least one `.machine <cpu>`. Otherwise, a parsing error is recognized.

>From 09027be3a46cd12b36db0b04ce1bc17e0013c142 Mon Sep 17 00:00:00 2001
From: Dominik Steenken <dost at de.ibm.com>
Date: Thu, 24 Apr 2025 11:38:22 +0200
Subject: [PATCH] [SystemZ] Implement .machine (push|pop) directives

The `.machine push` and `.machine pop` directives were missing from
the SystemZ Backend Asm Parser. This commit adds them, and expands the
corresponding test to test proper operation.
---
 .../SystemZ/AsmParser/SystemZAsmParser.cpp    | 38 ++++++++++++++++---
 .../MC/SystemZ/machine-directive-invalid.s    | 13 +++++--
 llvm/test/MC/SystemZ/machine-directive.s      |  3 +-
 3 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 6d9a7a73f72db..a7612ecfd954f 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -410,6 +410,12 @@ class SystemZAsmParser : public MCTargetAsmParser {
 
 private:
   MCAsmParser &Parser;
+
+  // A vector to contain the stack of machine specs created by `.machine push`
+  SmallVector<StringRef> MachineStack;
+  // Specifies the current CPU
+  StringRef CurrentCPU = "";
+
   enum RegisterGroup {
     RegGR,
     RegFP,
@@ -1382,17 +1388,37 @@ 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();
+
+  // Parse push and pop directives first
+  StringRef CPU = "";
+  if (Id == "push") {
+    if (CurrentCPU.empty())
+      return TokError(
+          "push without preceding cpu spec in '.machine' directive");
+    MachineStack.push_back(CurrentCPU);
+  } else if (Id == "pop") {
+    if (MachineStack.empty())
+      return TokError("pop without corresponding push in '.machine' directive");
+    CPU = MachineStack.back();
+    MachineStack.pop_back();
+  } else {
+    CPU = Id;
+  }
+
   Parser.Lex();
   if (parseEOL())
     return true;
 
-  MCSubtargetInfo &STI = copySTI();
-  STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
-  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
-
-  getTargetStreamer().emitMachine(CPU);
+  // check if we need to change cpu
+  if (!CPU.empty()) {
+    MCSubtargetInfo &STI = copySTI();
+    STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
+    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+    CurrentCPU = CPU;
 
+    getTargetStreamer().emitMachine(CPU);
+  }
   return false;
 }
 
diff --git a/llvm/test/MC/SystemZ/machine-directive-invalid.s b/llvm/test/MC/SystemZ/machine-directive-invalid.s
index 8b3147ecc62d4..f9e6aea4f2604 100644
--- a/llvm/test/MC/SystemZ/machine-directive-invalid.s
+++ b/llvm/test/MC/SystemZ/machine-directive-invalid.s
@@ -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 push
+// CHECK: :[[@LINE-1]]:10: error: push without preceding cpu spec in '.machine' directive
+
+.machine pop
+// CHECK: :[[@LINE-1]]:10: error: pop without corresponding push in '.machine' directive
 
-# 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
diff --git a/llvm/test/MC/SystemZ/machine-directive.s b/llvm/test/MC/SystemZ/machine-directive.s
index aa71c6aea5572..7861c56420cd3 100644
--- a/llvm/test/MC/SystemZ/machine-directive.s
+++ b/llvm/test/MC/SystemZ/machine-directive.s
@@ -12,9 +12,10 @@
 # CHECK: vgbm	%v0, 3
 
 .machine z13
+.machine push
 vgbm    %v0, 0
 .machine zEC12
 vgbm    %v0, 1
-.machine z13
+.machine pop
 vgbm    %v0, 3
 



More information about the llvm-commits mailing list