Aligning loops in Go assembly

313 views
Skip to first unread message

Wojciech Muła

unread,
Feb 24, 2022, 12:40:58 PM2/24/22
to golang-nuts

Hi all! That's my first post to the group.

I'm writing an implementation in x86 assembler and I need to force a certain alignment of blocks of code (as it affects performance). I found that there's PCALIGN directive, but it's only available for the PPC architecture. It does not work for x86.

Is there any easy way to achieve this for x86? If I had one loop, it won't be a problem --- I'd just put a few `BYTE $0x90` and move on. The problem is my code is huge, partially autogenerated with few variants.

Any hints?

regards
w.

Kurtis Rader

unread,
Feb 24, 2022, 3:23:55 PM2/24/22
to Wojciech Muła, golang-nuts
It's not clear what your question has to do with the Go language. Are you asking how to control the alignment of the code produced by the Go compiler? Some more context would probably help the community answer your question.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/cd4b3e00-0e36-4fa5-bf2b-9ac996198db1n%40googlegroups.com.


--
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank

Ian Lance Taylor

unread,
Feb 24, 2022, 8:21:41 PM2/24/22
to Wojciech Muła, golang-nuts
On Thu, Feb 24, 2022 at 9:40 AM Wojciech Muła <wojte...@gmail.com> wrote:
>
> I'm writing an implementation in x86 assembler and I need to force a certain alignment of blocks of code (as it affects performance). I found that there's PCALIGN directive, but it's only available for the PPC architecture. It does not work for x86.
>
> Is there any easy way to achieve this for x86? If I had one loop, it won't be a problem --- I'd just put a few `BYTE $0x90` and move on. The problem is my code is huge, partially autogenerated with few variants.
>
> Any hints?

As far as I can tell PCALIGN is implemented for all architectures.

Ian

Kurtis Rader

unread,
Feb 24, 2022, 8:48:44 PM2/24/22
to Ian Lance Taylor, Wojciech Muła, golang-nuts
On Thu, Feb 24, 2022 at 5:21 PM Ian Lance Taylor <ia...@golang.org> wrote:
On Thu, Feb 24, 2022 at 9:40 AM Wojciech Muła <wojte...@gmail.com> wrote:
>
> I'm writing an implementation in x86 assembler and I need to force a certain alignment of blocks of code (as it affects performance). I found that there's PCALIGN directive, but it's only available for the PPC architecture. It does not work for x86.
>
> Is there any easy way to achieve this for x86? If I had one loop, it won't be a problem --- I'd just put a few `BYTE $0x90` and move on. The problem is my code is huge, partially autogenerated with few variants.

As far as I can tell PCALIGN is implemented for all architectures.

See, for example, https://docs.studygolang.com/src/cmd/internal/obj/arm64/doc.go . I couldn't find a similar document for x86_64 (or even just x86 or i386). However, I did eventually find https://github.com/golang/go/blob/master/src/cmd/asm/internal/asm/asm.go which makes it clear the PCALIGN directive is supported for all architectures; albeit with different valid values. Perhaps the O.P. isn't using it correctly for x86. This seems like a feature that could be better documented. :-)

Wojciech Muła

unread,
Feb 25, 2022, 1:42:23 AM2/25/22
to golang-nuts
The directive is not documented on https://pkg.go.dev/cmd/internal/obj/x86. `grep -l -R PCALIGN *` run in `cmd/interal/obj` shows for the freshest master:

arm64/doc.go
arm64/asm7.go
arm64/asm_arm64_test.go
link.go
ppc64/doc.go
ppc64/asm9.go
ppc64/asm_test.go
util.go

Seems it's not implemented. When tried to use it, I got the following error:

# main
asm: asmins: missing op 00000 (<unknown line number>)        PCALIGN        $16
asm: assembly failed

Sample asm code to check this:

---asmfun_amd64.s---
#include "textflag.h"

TEXT ·asmfun(SB), NOSPLIT, $0
    PCALIGN $16
    RET
---eof---

---main.go---
package main

// go:noescape
func asmfun()
func main() { asmfun() }
---eof---

w.

Brian Candler

unread,
Feb 25, 2022, 3:35:10 AM2/25/22
to golang-nuts
It seems to me that there is automatic alignment for loops:

Brian Candler

unread,
Feb 25, 2022, 3:36:17 AM2/25/22
to golang-nuts
Oops, I see it's disabled; but the knob is there if you want to experiment.

Wojciech Muła

unread,
Feb 25, 2022, 4:25:32 AM2/25/22
to golang-nuts
Thanks! Didn't know that the assembler is able to do this. TBH, for me, it's not desired behaviour when an assembler program does something extra to a low-level code. I have already observed that Go asm strips a series of NOPs, which is highly unexpected.

A directive for alignment is way clearer. Not to mention that sometimes we don't need to align jump targets.

w.

Keith Randall

unread,
Feb 25, 2022, 11:42:26 AM2/25/22
to golang-nuts
I don't think PCALIGN is supported for x86. The assembler can parse the instruction, but the x86 assembler backend can't generate machine code for it.
Wouldn't be hard to add, I think. There's already disabled experimental code in there for aligning loops.

Ian Lance Taylor

unread,
Feb 25, 2022, 1:45:42 PM2/25/22
to Wojciech Muła, golang-nuts
On Fri, Feb 25, 2022 at 1:25 AM Wojciech Muła <wojte...@gmail.com> wrote:
>
> Thanks! Didn't know that the assembler is able to do this. TBH, for me, it's not desired behaviour when an assembler program does something extra to a low-level code. I have already observed that Go asm strips a series of NOPs, which is highly unexpected.

For better or for worse, the Go assembler is already a high-level
assembler that fiddles with your low-level code.

Ian
Reply all
Reply to author
Forward
0 new messages