[cfe-dev] asm directive: symbolic label syntax
Alexander von Below via cfe-dev
cfe-dev at lists.llvm.org
Mon Oct 11 08:20:35 PDT 2021
Hello Brian (and everyone who is reading this),
allow me to be very verbose (-vvvv) so that you, and others, can understand what I did, why I did it, and what I found:
## Motivation
The main objective was to provide an "Apple Companion Guide" to the book „Programming with 64-Bit ARM Assembly Language“ by Stephen Smith. The book uses the RaspberryPi 4, Linux and accordingly the GNU toolchain and GNU syntax. I wanted to provide both information on how Apple aarch64 devices differ, as well as modified, runnable source code. You can see all of what I did here: https://github.com/below/HelloSilicon
## The Problem
I ran into an issue when it came to an example using inline-assembly in C. Here is the original code, which works on ARM64 Linux, simply by invoking gcc on the file without any flags: https://github.com/below/HelloSilicon/blob/4c4b2911c43644adfd3b78aee093857444f28472/Chapter%209/uppertst4.c
When compiling the same exact file with clang on an M1 Mac (again, no flags), there is a trivial warning that we will ignore, and the following errors:
```
uppertst4.c:22:4: error: conditional branch requires assembler-local label. 'cont' is external.
"BGT cont\n"
^
<inline asm>:4:1: note: instantiated into assembly here
BGT cont
^
uppertst4.c:24:4: error: conditional branch requires assembler-local label. 'cont' is external.
"BLT cont\n"
^
<inline asm>:6:1: note: instantiated into assembly here
BLT cont
^
uppertst4.c:28:4: error: conditional branch requires assembler-local label. 'loop' is external.
"B.NE loop\n"
^
<inline asm>:10:1: note: instantiated into assembly here
B.NE loop
^
```
## The Provisional Solution
I was able to solve the issue by replacing the `cont` label with a numeric value, 2, and the branches with `BGT 2f` and `BLT 2f`. Curiously, after this change, `loop` could stay like it was.
## Finding The Real Problem
Other than the trivial warnings, godbolt is absolutely happy with the file: https://godbolt.org/z/6s8bs4rW9
Next, I let clang create assembly output using `clang -S uppertst4.c` (on the M1 Mac) on the original, GNU, sourcefile. This also produces no errors, however trying to invoke the clang assembler `as` did:
```
% as uppertst4.s
uppertst4.s:33:2: error: conditional branch requires assembler-local label. 'cont' is external.
b.gt cont
^
uppertst4.s:35:2: error: conditional branch requires assembler-local label. 'cont' is external.
b.lt cont
^
uppertst4.s:40:2: error: conditional branch requires assembler-local label. 'loop' is external.
b.ne loop
^
```
As I had a [working, standalone assembly file](https://github.com/below/HelloSilicon/blob/main/Chapter%2005/upper.s) which uses both `cont` and `loop`, I took a „divide and conquer“ approach: I deleted and added lines to the two files, until I would know what precisely caused the issue.
It turned out to be on the very last line, clang adds the compiler directive: `.subsections_via_symbols`.
llvm does it whenever it outputs assembly for a MachO binary, the source code tells us:
```
if (TT.isOSBinFormatMachO()) {
// Funny Darwin hack: This flag tells the linker that no global symbols
// contain code that falls through to other global symbols (e.g. the obvious
// implementation of multiple entry points). If this doesn't occur, the
// linker can safely perform dead code stripping. Since LLVM never
// generates code that does this, it is always safe to set.
OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
}
```
https://github.com/llvm/llvm-project/blob/89b57061f7b769e9ea9bf6ed686e284f3e55affe/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp#L568
The part about "Since LLVM never generates code that does this“ of course leaves out code that llvm did not generate, such as inline-assembly.
## The Real Solution
Because the C-Frontend created its own symbolic forward label, I learned that to remedy my issue, I needed to prefix `cont` with `L`, whereever using it. Here is the final file for ARM64 on Mac: https://github.com/below/HelloSilicon/blob/main/Chapter%2009/uppertst4.c
## What I still don’t know
While I did not take the time to fully understand what `. subsections_via_symbols` does, and still being a learner about these things, three questions remain:
1) What precisely was the violation of the inline code? Are there "global symbols which contain code that falls through to other global symbols“?
2) Why is the `loop` label apparently not a problem? Just to be sure, I changed it’s name to something not beginning with `l`, but that did not cause any issue either
3) Is there a substantial issue in my the standalone assembly code that I should know about?
So thank you for bearing with me. If you have any questions of input, please let me know!
Alex
> Am 11.10.2021 um 14:12 schrieb Brian Cain <brian.cain at gmail.com>:
>
> Can you post a godbolt link? that would also show which command line options you're using.
>
> So this is with gas and -fno-integrated-as?
>
> On Mon, Oct 11, 2021, 1:42 AM Alexander von Below <below at mac.com> wrote:
> Hello,
>
> one thing I should stress: This appears to be a C-Frontend issue (and thus I am posting it here) because when using as directly, this problem does not occur: https://github.com/below/HelloSilicon/blob/main/Chapter%2005/upper.s
>
> I have taken your suggestions: Changing the name of „cont“ to something that does not sound like a keyword does not help.
> Adding a ".global _faz\n“ (or ".global faz“) does not change anything, neither does „BGT .Lfaz\n“ seem to have any effect.
>
> Let me know if you have any other ideas
>
> Thanks
>
> Alex
>
> > Am 11.10.2021 um 01:59 schrieb Brian Cain <brian.cain at gmail.com>:
> >
> > Does the behavior change if you declare "cont" as a global symbol? Does the symbol have to be "cont"? Would ".Lcont" suffice? Many targets treat leading ".L" as implicitly local symbols.
> >
> > On Sun, Oct 10, 2021 at 6:30 PM Alexander von Below via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> > Thanks a lot for your answer, and yes, I do:
> >
> > Working code (using numeric label): https://github.com/below/HelloSilicon/blob/main/Chapter%2009/uppertst4.c
> > Non-working (original) code: https://github.com/below/HelloSilicon/blob/4c4b2911c43644adfd3b78aee093857444f28472/Chapter%209/uppertst4.c
> >
> > Compile using the makefile in the same folder, or using "clang -o uppertst4 uppertst4.c“
> >
> > On godbolt, running the original code through armv8-a-clang 11.0.1 or trunk, everything seems to work fine. There is an unrelated warning, but no errors. The output shows both the loop and the cont labels: https://godbolt.org/z/xY5afcYdW
> >
> > Compiling the code with the symbolic cont label on an M1 using clang-1300.0.29.3 produces the errors:
> >
> > uppertst4.c:22:4: error: conditional branch requires assembler-local label. 'cont' is external.
> > "BGT cont\n"
> > ^
> > <inline asm>:4:1: note: instantiated into assembly here
> > BGT cont
> > ^
> > uppertst4.c:24:4: error: conditional branch requires assembler-local label. 'cont' is external.
> > "BLT cont\n"
> > ^
> > <inline asm>:6:1: note: instantiated into assembly here
> > BLT cont
> > ^
> > uppertst4.c:28:4: error: conditional branch requires assembler-local label. 'loop' is external.
> > "B.NE loop\n"
> > ^
> > <inline asm>:10:1: note: instantiated into assembly here
> > B.NE loop
> > ^
> >
> > Notably, now for both loop and cont, while it is sufficient to replace cont with a numeric label.
> >
> > I would be glad to find out if I am doing it wrong, or if this is an issue in clang. And now my curiosity is raised why godbolt appears to differ from clang on macOS …
> >
> > Thanks again
> >
> > Alex
> >
> >
> > > Am 11.10.2021 um 00:26 schrieb Joerg Sonnenberger via cfe-dev <cfe-dev at lists.llvm.org>:
> > >
> > > On Sun, Oct 10, 2021 at 12:27:28PM +0200, Alexander von Below via cfe-dev wrote:
> > >> I have tried to adapt gnu as code for Apple Silicon, and I have found
> > >> explanations for most differences. There is one issue I still have:
> > >
> > > Do you actually have a complete self-contained example? Try godbolt.org.
> > >
> > > Joerg
> > > _______________________________________________
> > > cfe-dev mailing list
> > > cfe-dev at lists.llvm.org
> > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
> >
> > _______________________________________________
> > cfe-dev mailing list
> > cfe-dev at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
> >
> >
> > --
> > -Brian
>
More information about the cfe-dev
mailing list