This is a generalization of the LookupPtrRegClass mechanism.
AMDGPU has several use cases for swapping the register class of
instruction operands based on the subtarget, but none of them
really fit into the box of being pointer-like.
The current system requires manual management of an arbitrary integer
ID. For the AMDGPU use case, this would end up being around 40 new
entries to manage.
This just introduces the base infrastructure. I have ports of all
the target specific usage of PointerLikeRegClass ready.
Printing an expression is error-prone without a MCAsmInfo argument.
Remove the operator<< overload and replace callers with
MCAsmInfo::printExpr. Some callers are changed to MCExpr::print, with
the goal of eventually making it private.
so that subclasses can provide the appropriate MCAsmInfo to print
MCExpr objects.
At present, llvm/utils/TableGen/AsmMatcherEmitter.cpp constucts a
generic MCAsmInfo.
MCExpr::print has an optional MCAsmInfo argument, which is error-prone
when omitted. MCExpr::print and the convenience helper operator<< are
discouraged to use. Switch to MCAsmInfo::printExpr instead. Use the
target-specific MCAsmInfo if available.
## Purpose
This patch is one in a series of code-mods that annotate LLVM’s public
interface for export. This patch annotates the `llvm/Target` library.
These annotations currently have no meaningful impact on the LLVM build;
however, they are a prerequisite to support an LLVM Windows DLL (shared
library) build.
## Background
This effort is tracked in #109483. Additional context is provided in
[this
discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307),
and documentation for `LLVM_ABI` and related annotations is found in the
LLVM repo
[here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).
A sub-set of these changes were generated automatically using the
[Interface Definition Scanner (IDS)](https://github.com/compnerd/ids)
tool, followed formatting with `git clang-format`.
The bulk of this change is manual additions of `LLVM_ABI` to
`LLVMInitializeX` functions defined in .cpp files under llvm/lib/Target.
Adding `LLVM_ABI` to the function implementation is required here
because they do not `#include "llvm/Support/TargetSelect.h"`, which
contains the declarations for this functions and was already updated
with `LLVM_ABI` in a previous patch. I considered patching these files
with `#include "llvm/Support/TargetSelect.h"` instead, but since
TargetSelect.h is a large file with a bunch of preprocessor x-macro
stuff in it I was concerned it would unnecessarily impact compile times.
In addition, a number of unit tests under llvm/unittests/Target required
additional dependencies to make them build correctly against the LLVM
DLL on Windows using MSVC.
## Validation
Local builds and tests to validate cross-platform compatibility. This
included llvm, clang, and lldb on the following configurations:
- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang
z/OS creates SystemZMCExpr objects (https://reviews.llvm.org/D153788)
while ELF doesn't. Define the SystemZMCAsmInfoGOFF hooks
instead of the legacy MCSpecifierExpr:: hooks.
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>`.
- _Float16 is now accepted by Clang.
- The half IR type is fully handled by the backend.
- These values are passed in FP registers and converted to/from float around
each operation.
- Compiler-rt conversion functions are now built for s390x including the missing
extendhfdf2 which was added.
Fixes#50374
Similar to previous migration done for other targets (PowerPC, X86, ARM,
etc). Switch from the confusing VariantKind to Specifier, which aligns
with Arm and IBM AIX's documentation.
In addition, rename *MCExpr::getKind, which confusingly shadows the base class getKind.
In the future, relocation specifiers should be encoded as part of
SystemZMCExpr instead of MCSymbolRefExpr.
This patch adds support for the next-generation arch15
CPU architecture to the SystemZ backend.
This includes:
- Basic support for the new processor and its features.
- Detection of arch15 as host processor.
- Assembler/disassembler support for new instructions.
- Exploitation of new instructions for code generation.
- New vector (signed|unsigned|bool) __int128 data types.
- New LLVM intrinsics for certain new instructions.
- Support for low-level builtins mapped to new LLVM intrinsics.
- New high-level intrinsics in vecintrin.h.
- Indicate support by defining __VEC__ == 10305.
Note: No currently available Z system supports the arch15
architecture. Once new systems become available, the
official system name will be added as supported -march name.
When parsing an address that contains only a single register
for an instruction that actually has both a base and an index
register, the parsed register is treated as base by AsmParser.
This is correct when emulating the GNU assembler, but not when
emulating HLASM, as the latter treat the register as index in
this case.
The LLVM AsmParser showed different behavior compared to GAS when
parsing address operands in the following two ways:
- If the address operand only has a single register (no comma),
it is always interpreted as base register by GAS, even in the
vector-index case (vgef etc.) This means the following is
actually incorrect usage, as the base cannot be a vector
register: vgef %v0, 0(%v1), 0.
- GAS allows specifying a missing base register by using a
comma after the first register, e.g. vgef %v0, 0(%v1,), 0.
In preparation for future work on separating the output of the GNU/HLASM
ASM dialects, we first separate the SystemZInstPrinter classes to two
versions, one for each ASM dialect.
The common code remains in a SystemZInstPrinterCommon class instead.
---------
Co-authored-by: Tony Tao <tonytao@ca.ibm.com>
The ATT assembler dialect on SystemZ seems to have been taken from the
existing ATT/Intel code. However, on SystemZ, ATT does not hold any
meaning. In reality, we are splitting the difference between GNU Asm
syntax and HLASM Asm syntax, so it makes sense to rename ATT to GNU
instead.
Co-authored-by: Tony Tao <tonytao@ca.ibm.com>
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.
I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
Most addresses in SystemZ instructions take two registers,
an index register and a base register. However, either of
those can be omitted. If there is just a single register,
this usually is taken as the base register - however, there
are certain rare cases where you specifically want to use
an index register but no base register. This is currently
not handled consistently by the assembler / disassembler.
Fix this by
- always emitting a dummy 0 as base register for index-
only addresses
- correctly handle dummy 0 as indicating no base register
when parsing an address
This is compatible with current GNU binutils behavior.
Some fixes for style issues pointed out by clang-tidy:
- Upper case/lower case fixes
- No else after return
- Removed unused #include's
- Added NOLINTNEXTLINE() for the LLVM* functions
All changes are NFC.
This finishes the work of replacing OperandMatchResultTy with
ParseStatus, started in D154101.
As a drive-by change, rename some RegNo variables to just Reg
(a leftover from the days when RegNo had 'unsigned' type).
ParseStatus is slightly more convenient to use due to implicit
conversion from bool, which allows to do something like:
```
return Error(L, "msg");
```
when with MatchOperandResultTy it had to be:
```
Error(L, "msg");
return MatchOperand_ParseFail;
```
It also has more appropriate name since parse* methods are not only for
parsing operands.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D154316
Currently mentioning any symbols in immediate asm operands is not
supported, for example:
error: invalid operand for instruction
lghi %r4,foo_end-foo
The immediate problem is that is*Imm() and print*Operand() functions do
not accept MCExprs, but simply relaxing these checks is not enough:
after symbol addresses are computed, range checks need to run against
resolved values.
Add a number of SystemZ::FixupKind members for each kind of immediate
value and process them in SystemZMCAsmBackend::applyFixup(). Only
perform the range checks, do not change anything.
Adjust the tests: move previously failing cases like the one shown
above out of insn-bad.s.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D154899
Conventionally, parsing methods return false on success and true on
error. However, directive parsing methods need a third state: the
directive is not target specific. AsmParser::parseStatement detected
this case by using a fragile heuristic: if the target parser did not
consume any tokens, the directive is assumed to be not target-specific.
Some targets fail to follow the convention: they return success after
emitting an error or do not consume the entire line and return failure
on successful parsing. This was partially worked around by checking for
pending errors in parseStatement.
This patch tries to improve the situation by introducing parseDirective
method that returns ParseStatus -- three-state class. The new method
should eventually replace the old one returning bool.
ParseStatus is intentionally implicitly constructible from bool to allow
uses like `return Error(Loc, "message")`. It also has a potential to
replace OperandMatchResulTy as it is more convenient to use due to the
implicit construction from bool and more type safe.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D154101
In preparation for removing the `#include "llvm/ADT/StringExtras.h"`
from the header to source file of `llvm/Support/Error.h`, first add in
all the missing includes that were previously included transitively
through this header.
On SystemZ, the vector ABI changes depending on the presence of hardware
vector support. Therefore, each binary compiled with a visible vector ABI
(e.g. one that calls an external function with a vector argument) should be
marked with a .gnu_attribute describing this.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D105067
Clang does not accept instructions like brasl %r0,.-0x100000000,
because the second operand's right-hand-side (0x100000000) barely
misses the acceptable range. However, since it's being subtracted, it
makes sense to perform the range check on the negated value.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D124780
As usual with that header cleanup series, some implicit dependencies now need to
be explicit:
llvm/MC/MCParser/MCAsmParser.h no longer includes llvm/MC/MCParser/MCAsmLexer.h
Preprocessed lines to build llvm on my setup:
after: 1068185081
before: 1068324320
So no compile time benefit to expect, but we still get the looser coupling
between files which is great.
Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup
Differential Revision: https://reviews.llvm.org/D119359
This patch adds support for symbolic displacements, e.g. like 'lg %r0,
sym(%r1)', which is done using relocations. This is needed to compile the
kernel without disabling the integrated assembler.
Review: Ulrich Weigand
Differential Revision: https://reviews.llvm.org/D113341
This moves the registry higher in the LLVM library dependency stack.
Every client of the target registry needs to link against MC anyway to
actually use the target, so we might as well move this out of Support.
This allows us to ensure that Support doesn't have includes from MC/*.
Differential Revision: https://reviews.llvm.org/D111454
Note that SystemZMnemonicSpellCheck is defined in
SystemZGenAsmMatcher.inc, which SystemZAsmParser.cpp includes.
Identified with readability-redundant-declaration.
The .machine directive can be used in assembly files to specify the ISA for
the instructions following it.
Review: Ulrich Weigand
Differential Revision: https://reviews.llvm.org/D109660
- This patch (is one in a series of patches) which introduces HLASM Parser support (for the first parameter of inline asm statements) to LLVM ([[ https://lists.llvm.org/pipermail/llvm-dev/2021-January/147686.html | main RFC here ]])
- This patch in particular introduces HLASM Parser support for Z machine instructions.
- The approach taken here was to subclass `AsmParser`, and make various functions and variables as "protected" wherever appropriate.
- The `HLASMAsmParser` class overrides the `parseStatement` function. Two new private functions `parseAsHLASMLabel` and `parseAsMachineInstruction` are introduced as well.
The general syntax is laid out as follows (more information available in [[ https://www.ibm.com/support/knowledgecenter/SSENW6_1.6.0/com.ibm.hlasm.v1r6.asm/asmr1023.pdf | HLASM V1R6 Language Reference Manual ]] - Chapter 2 - Instruction Statement Format):
```
<TokA><spaces.*><TokB><spaces.*><TokC><spaces.*><TokD>
```
1. TokA is referred to as the Name Entry. This token is optional
2. TokB is referred to as the Operation Entry. This token is mandatory.
3. TokC is referred to as the Operand Entry. This token is mandatory
4. TokD is referred to as the Remarks Entry. This token is optional
- If TokA is provided, then we either parse TokA as a possible comment or as a label (Name Entry), Tok B as the Operation Entry and so on.
- If TokA is not provided (i.e. we have one or more spaces and then the first token), then we will parse the first token (i.e TokB) as a possible Z machine instruction, TokC as the operands to the Z machine instruction and TokD as a possible Remark field
- TokC (Operand Entry), no spaces are allowed between OperandEntries. If a space occurs it is classified as an error.
- TokD if provided is taken as is, and emitted as a comment.
The following additional approach was examined, but not taken:
- Adding custom private only functions to base AsmParser class, and only invoking them for z/OS. While this would eliminate the need for another child class, these private functions would be of non-use to every other target. Similarly, adding any pure virtual functions to the base MCAsmParser class and overriding them in AsmParser would also have the same disadvantage.
Testing:
- This patch doesn't have tests added with it, for the sole reason that MCStreamer Support and Object File support hasn't been added for the z/OS target (yet). Hence, it's not possible generate code outright for the z/OS target. They are in the process of being committed / process of being worked on.
- Any comments / feedback on how to combat this "lack of testing" due to other missing required features is appreciated.
Reviewed By: Kai, uweigand
Differential Revision: https://reviews.llvm.org/D98276
- This patch attempts to implement the location counter syntax (*) for the HLASM variant for PC-relative instructions.
- In the HLASM variant, for purely constant relocatable values, we expect a * token preceding it, with special support for " *" which is parsed as "<pc-rel-insn 0>"
- For combinations of absolute values and relocatable values, we don't expect the "*" preceding the token.
When you have a " * " what’s accepted is:
```
*<space>.*{.*} -> <pc-rel-insn> 0
*[+|-][constant-value] -> <pc-rel-insn> [+|-]constant-value
```
When you don’t have a " * " what’s accepted is:
```
brasl 1,func is allowed (MCSymbolRef type)
brasl 1,func+4 is allowed (MCBinary type)
brasl 1,4+func is allowed (MCBinary type)
brasl 1,-4+func is allowed (MCBinary type)
brasl 1,func-4 is allowed (MCBinary type)
brasl 1,*func is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*+func is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*+func+4 is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*+4+func is not allowed (* cannot be used for non-MCConstantExprs)
brasl 1,*-4+8+func is not allowed (* cannot be used for non-MCConstantExprs)
```
Reviewed By: Kai
Differential Revision: https://reviews.llvm.org/D100987
- Previously, https://reviews.llvm.org/D101308 removed prefixes from register while printing them out. This was especially needed for inline asm statements which used input/output operands.
- However, the backend SystemZAsmParser, accepts both prefixed registers and prefix-less registers as part of its implementation
- This patch aims to change that by ensuring that prefixed registers are only allowed for the ATT dialect.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D101665
- In the SystemZAsmParser, there will be a few queries to the type of dialect it is (AD_ATT, AD_HLASM) in future patches.
- It would be nice to have two small helper functions `isParsingATT()` and `isParsingHLASM()`
- Putting this as a separate smaller patch allows us to remove its definitions from other dependent patches.
Reviewed By: uweigand, abhina.sreeskantharajan
Differential Revision: https://reviews.llvm.org/D99891
- This patch adds in support to determine whether a particular label
is valid for the hlasm variant
- The label syntax being checked is that of an ordinary HLASM symbol
(Reference, Chapter 2 (Coding and Structure) - Terms, Literals and
Expressions - Terms - Symbols - Ordinary Symbol)
- To achieve this, the virtual function isLabel defined in
MCTargetAsmParser.h is made use of
- The isLabel function is overridden in SystemZAsmParser for the
hlasm variant, and the syntax is checked appropriately
- Things remain unchanged for the att variant
- Further patches will add in support to emit the label. These future
patches will make use of this isLabel function
Reviewed By: uweigand, Kai
Differential Revision: https://reviews.llvm.org/D97748
- This patch introduces a different assembler dialect ("hlasm") for z/OS.
The default dialect has now been given the "att" dialect name. For this
appropriate changes have been added to SystemZ.td.
- This patch also makes a few changes to SystemZInstrFormats.td which
restrict a few condition code mnemonics to just the "att" dialect
variant (he, le, lh, nhe, nle, nlh). These extended condition code
mnemonics are not available in HLASM.
- A new private function has been introduced in SystemZAsmParser.cpp to
return the assembler dialect set in SystemZMCAsmInfo.cpp. The reason we
couldn't/haven't explicitly queried the overriden getAssemblerDialect
function from AsmParser is outlined in this thread here. This returned
dialect is directly passed onto the relevant matcher functions which taken
in a variantID, so that the matcher functions can appropriately choose an
instruction based on the variant.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D94250
This patch consists of the addition of some common additional
extended mnemonics to the SystemZ target.
- These are jnop, jct, jctg, jas, jasl, jxh, jxhg, jxle,
jxleg, bru, brul, br*, br*l.
- These mnemonics and the instructions they map to are
defined here, Chapter 4 - Branching with extended
mnemonic codes.
- Except for jnop (which is a variant of brc 0, label), every
other mnemonic is marked as a MnemonicAlias since there is
already a "defined" instruction with the same encoding
and/or condition mask values.
- brc 0, label doesn't have a defined extended mnemonic, thus
jnop is defined using as an InstAlias. Furthermore, the
applyMnemonicAliases function is called in the overridden
parseInstruction function in SystemZAsmParser.cpp to ensure
any mnemonic aliases are applied before any further
processing on the instruction is done.
Reviewed By: uweigand
Differential Revision: https://reviews.llvm.org/D92185
This patch makes the parser
- reject higher vector registers (>=16) in operands where they should not
be accepted.
- accept higher integers (>=16) in vector register operands.
Review: Ulrich Weigand
Differential Revision: https://reviews.llvm.org/D88888
Support VRI, VRR, VRS, VRV, VRX, VSI instruction formats with the .insn
directive.
Review: Ulrich Weigand
Differential Revision: https://reviews.llvm.org/D88357
Revision e1de2773a534957305d7a559c6d88c4b5ac354e2 provided support for
accepting integer registers in inline asm i.e.
__asm("lhi %r0, 5") -> lhi %r0, 5
__asm("lhi 0, 5") -> lhi 0,5
This patch aims to extend this support to instructions which compute
addresses as well. (i.e instructions of type BDMem and BD[X|R|V|L]Mem)
Author: anirudhp
Differential Revision: https://reviews.llvm.org/D83251
For compatibility with other assemblers on the platform, allow
using just plain integer register numbers in all places where a
register operand is expected.
Bug: llvm.org/PR45582