FAQ
Hi!

I was getting annoyed by all the different formatting styles of assembler
code. My thought was, that we have "solved" that very nicely with Go, by
having a standard formatter, so I set out to do the same for assembly files.

Here is the result:

https://github.com/klauspost/asmfmt


It does the following reformatting:

* Automatic indentation.
* It uses tabs for indentation and blanks for alignment (as gofmt).
* It will remove trailing whitespace.
* It will align the first parameter.
* It will align all comments in a block.
* It will eliminate multiple blank lines.
* Forced newline before comments, except when preceded by label or another
comment.
* Forced newline before labels, except when preceded by comment.
* Retains block breaks (newline between blocks).
* It will convert single line block comments to line comments.
* Line comments have a space after `//`, except if comment starts with `+`.
* There is always a space between parameters.
* Macros in the same file are tracked, and not included in parameter
indentation.
* `TEXT`, `DATA` and `GLOBL` and labels are level 0 indentation.
* Aligns `\` in multiline macros in blocks.


There is a standalone command, called `asmfmt`, with similar syntax as
gofmt, which operates on ".s" assembler files. There are replacements for
`gofmt`, `goreturns` and `goimports`, which also processes ".s" files when
processing a package.

I am looking for feedback before "locking" the format. When testing, you
should of course back up your files.

Does it do any stupid formatting? Does it break anything? Does it miss
something?


Thanks!

/Klaus

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Michael Hudson-Doyle at Nov 30, 2015 at 9:39 pm
    I like the idea. I ran it over some of the code in the Go source and
    most changes it makes are to the padding between the instruction and
    the operand.

    For my opinion on the colour of the bikeshed, I think using a single
    tab after the instruction (if there are any arguments) works better:
    there aren't many (any?) real instructions with mnemonics longer than
    8 characters and while there are a few macros that have longer names
    (e.g. NO_LOCAL_POINTERS) they don't have arguments anyway. I don't
    trust gmail or google groups with anything containing tab characters
    so I put an example in a gist:
    https://gist.github.com/mwhudson/505e53d5f24a22764ed2

    Cheers,
    mwh

    On 1 December 2015 at 04:44, Klaus Post wrote:
    Hi!

    I was getting annoyed by all the different formatting styles of assembler
    code. My thought was, that we have "solved" that very nicely with Go, by
    having a standard formatter, so I set out to do the same for assembly files.

    Here is the result:

    https://github.com/klauspost/asmfmt


    It does the following reformatting:

    * Automatic indentation.
    * It uses tabs for indentation and blanks for alignment (as gofmt).
    * It will remove trailing whitespace.
    * It will align the first parameter.
    * It will align all comments in a block.
    * It will eliminate multiple blank lines.
    * Forced newline before comments, except when preceded by label or another
    comment.
    * Forced newline before labels, except when preceded by comment.
    * Retains block breaks (newline between blocks).
    * It will convert single line block comments to line comments.
    * Line comments have a space after `//`, except if comment starts with `+`.
    * There is always a space between parameters.
    * Macros in the same file are tracked, and not included in parameter
    indentation.
    * `TEXT`, `DATA` and `GLOBL` and labels are level 0 indentation.
    * Aligns `\` in multiline macros in blocks.


    There is a standalone command, called `asmfmt`, with similar syntax as
    gofmt, which operates on ".s" assembler files. There are replacements for
    `gofmt`, `goreturns` and `goimports`, which also processes ".s" files when
    processing a package.

    I am looking for feedback before "locking" the format. When testing, you
    should of course back up your files.

    Does it do any stupid formatting? Does it break anything? Does it miss
    something?


    Thanks!

    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Damian Gryski at Dec 1, 2015 at 9:16 am

    On Monday, November 30, 2015 at 4:44:53 PM UTC+1, Klaus Post wrote:

    Does it do any stupid formatting? Does it break anything? Does it miss
    something?
    Running it over github.com/dchest/siphash , it indents the comment above
    blocks(). I would expect that comment to be flush to the start of the line.
    https://github.com/dchest/siphash/blob/master/blocks_amd64.s#L19

    Damian


    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Klaus Post at Dec 1, 2015 at 9:58 am

    @ Michael:
    I think using a single tab after the instruction (if there are any
    arguments) works better.

    I considered it, but discarded it for multiple reasons:

    * With spaces we get the parameters as closely aligned to the instruction
    as possible. That makes it easier to read, since your eyes don't have to
    "scroll" longer than possible.
    * It is tab size independent. With spaces, we get "perfect" alignment,
    since the tab size only affects the leftmost indentation, which doesn't
    affect alignment of comments.
    * There are instructions that are >7 characters, PCLMULQDQ comes to mind,
    with AVX+ it gets to instructions like VSCATTERPF1DPS. NO_LOCAL_POINTERS is
    a defined macro, so we ignore that for indentation.

    Your example is good. I assume that "INVOKE_SYSCALL" is an externally
    defined macro? There is no real way of distinctly identify these. If you
    put a parenthesis on it, it will be assumed to be so. We could check if the
    "instruction" contains an underscore, and if so also assume it to be a
    macro, though that only solves this case.


    @Damian:

    Running it over github.com/dchest/siphash , it indents the comment above
    blocks(). I would expect that comment to be flush to the start of the line.
    https://github.com/dchest/siphash/blob/master/blocks_amd64.s#L19
    It definitely should be. I will add a case for end of multi-line macro
    definitions.



    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Klaus Post at Dec 1, 2015 at 12:38 pm
    Hi!

    I have added the multi-line macro definition case, which now resets
    indentation properly.

    I have added come of the siphash files as test cases.

    Other minor changes:
    * Labels are on a separate line from any instructions.
    * Keep converted block->single line comments on the same line as the source.
    * Don't indent end-of-block comment marker unless last line started the
    comment, or a * was first non-space character on last line.
    * Don't add single line space if first character after single-line comment
    start is '/'
    * Fix rare whitespace slipping through.

    Thanks for the feedback so far, it is very helpful!


    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Rob Pike at Dec 1, 2015 at 4:15 pm
    I too would prefer a single tab after the instruction. That's what tabs are
    for: alignment. Using a tab removes questions of how wide a space is, such
    as when looking on a web page or using a regular font rather than a
    fixed-width one.

    -rob

    On Tue, Dec 1, 2015 at 4:38 AM, Klaus Post wrote:

    Hi!

    I have added the multi-line macro definition case, which now resets
    indentation properly.

    I have added come of the siphash files as test cases.

    Other minor changes:
    * Labels are on a separate line from any instructions.
    * Keep converted block->single line comments on the same line as the
    source.
    * Don't indent end-of-block comment marker unless last line started the
    comment, or a * was first non-space character on last line.
    * Don't add single line space if first character after single-line comment
    start is '/'
    * Fix rare whitespace slipping through.

    Thanks for the feedback so far, it is very helpful!


    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Aram Hăvărneanu at Dec 1, 2015 at 5:46 pm

    On Tue, Dec 1, 2015 at 5:14 PM, Rob Pike wrote:
    That's what tabs are for: alignment. Using a tab removes questions of how
    wide a space is, such as when looking on a web page or using a regular font
    rather than a fixed-width one.
    What about struct fields?

    --
    Aram Hăvărneanu

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Rob Pike at Dec 1, 2015 at 7:01 pm
    There are no structs in assembler, but if you've changed the subject to
    gofmt I would prefer a single tab there too, but I didn't get my way. In
    matters of formatting I rarely do.

    -rob

    On Tue, Dec 1, 2015 at 9:46 AM, Aram Hăvărneanu wrote:
    On Tue, Dec 1, 2015 at 5:14 PM, Rob Pike wrote:
    That's what tabs are for: alignment. Using a tab removes questions of how
    wide a space is, such as when looking on a web page or using a regular font
    rather than a fixed-width one.
    What about struct fields?

    --
    Aram Hăvărneanu
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Klaus Post at Dec 1, 2015 at 9:17 pm

    On Tuesday, 1 December 2015 17:15:32 UTC+1, Rob 'Commander' Pike wrote:

    I too would prefer a single tab after the instruction. That's what tabs
    are for: alignment. Using a tab removes questions of how wide a space is,
    such as when looking on a web page or using a regular font rather than a
    fixed-width one.
    I have created a branch with tab between the instruction and the first
    parameter.

    https://github.com/klauspost/asmfmt/pull/2

    With tab size 8, it looks mostly fine, with only a few indentation issues.
    With tab size 4 (my personal setting), it becomes very messy, since there
    are a lot of 3 character instructions.

    I don't encounter code in variable width font that often so I would
    personally prefer it to be fixed-width representation. It is of course only
    an issue when there are end-of-line comments, but I don't like that
    formatting gives it a "jumbled" look, where comments jump in indentation
    within a block.

    The alternative - to assume a tab size and insert a variable number of
    tabs/spaces - also don't appeal to me, since that leaves out the
    flexibility of using custom tab sizes. Also, it doesn't really solve the
    issue we are trying to solve; consistent indentation with variable-width
    fonts.


    I have taken a few screenshots. One with tab size 4, and three with 8 to
    illustrate some of the issues I see:

    http://imgur.com/a/KQnAT


    I think gofmt made it "right", by choosing spaces, and while there are some
    downsides I think the alternative is worse.

    PS. TEXT should not have tab before its parameter, since it looks silly, so
    ignore that for now. Maybe BYTE also shouldn't - it makes common
    semicolon-separated entries very long.

    -rob
    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Fatih Arslan at Dec 1, 2015 at 9:40 pm
    Just a side note of my experiences while implementing hclfmt
    (https://github.com/fatih/hclfmt).

    I have used spaces for indenting comments or array items. Tabs are not
    sufficient for these kind of alignments. And as I remember, gofmt uses
    space for indenting comments of statements that are one liner too,
    otherwise it uses tabs for aligning the statements.

    I've also experienced the issue with long variable names (as seen in
    the screenshot), and neglected using tabs for indenting comments or
    array items.
    On Tue, Dec 1, 2015 at 11:17 PM, Klaus Post wrote:
    On Tuesday, 1 December 2015 17:15:32 UTC+1, Rob 'Commander' Pike wrote:

    I too would prefer a single tab after the instruction. That's what tabs
    are for: alignment. Using a tab removes questions of how wide a space is,
    such as when looking on a web page or using a regular font rather than a
    fixed-width one.

    I have created a branch with tab between the instruction and the first
    parameter.

    https://github.com/klauspost/asmfmt/pull/2

    With tab size 8, it looks mostly fine, with only a few indentation issues.
    With tab size 4 (my personal setting), it becomes very messy, since there
    are a lot of 3 character instructions.

    I don't encounter code in variable width font that often so I would
    personally prefer it to be fixed-width representation. It is of course only
    an issue when there are end-of-line comments, but I don't like that
    formatting gives it a "jumbled" look, where comments jump in indentation
    within a block.

    The alternative - to assume a tab size and insert a variable number of
    tabs/spaces - also don't appeal to me, since that leaves out the flexibility
    of using custom tab sizes. Also, it doesn't really solve the issue we are
    trying to solve; consistent indentation with variable-width fonts.


    I have taken a few screenshots. One with tab size 4, and three with 8 to
    illustrate some of the issues I see:

    http://imgur.com/a/KQnAT


    I think gofmt made it "right", by choosing spaces, and while there are some
    downsides I think the alternative is worse.

    PS. TEXT should not have tab before its parameter, since it looks silly, so
    ignore that for now. Maybe BYTE also shouldn't - it makes common
    semicolon-separated entries very long.
    -rob

    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Andrey mirtchovski at Dec 1, 2015 at 10:24 pm

    I have created a branch with tab between the instruction and the first
    parameter.
    [...]
    I think we can settle this one issue about tabs and elastic spaces
    like all other Go formatting bikesheds: "what does gofmt do?". let's
    stick to that answer, it has been proven in the field :)

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Benoît Amiaux at Dec 1, 2015 at 11:22 pm
    Thank you, this is quite appreciated !
    I'm in favor of having all parameters aligned regardless of the instruction
    size, whatever the method.
    I would also put some padding and not try to match the smallest alignment,
    so we don't get a whole file diff when adding one instruction.
    I don't care if blocks are indented with spaces or tabs though
    So, spaces for alignment, tabs for indentation, (like in gofmt ?)

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nick Craig-Wood at Dec 2, 2015 at 10:24 am
    I had a go with it on https://github.com/ncw/iprime

    The complicated macros there, eg MOD_REDUCE with its token pasting seems
    to confuse it rather.

    That said, I just discovered that those files don't even compile with
    1.5 for reasons I haven't got time to work out just now, so maybe that
    isn't the best of tests!

    Anyway I'm very supportive of the idea, and not that fussy what the
    result looks like - it will look better and more consistent than what I
    managed by hand!
    On 30/11/15 15:44, Klaus Post wrote:
    Hi!

    I was getting annoyed by all the different formatting styles of
    assembler code. My thought was, that we have "solved" that very nicely
    with Go, by having a standard formatter, so I set out to do the same for
    assembly files.

    Here is the result:

    https://github.com/klauspost/asmfmt


    It does the following reformatting:

    * Automatic indentation.
    * It uses tabs for indentation and blanks for alignment (as gofmt).
    * It will remove trailing whitespace.
    * It will align the first parameter.
    * It will align all comments in a block.
    * It will eliminate multiple blank lines.
    * Forced newline before comments, except when preceded by label or
    another comment.
    * Forced newline before labels, except when preceded by comment.
    * Retains block breaks (newline between blocks).
    * It will convert single line block comments to line comments.
    * Line comments have a space after `//`, except if comment starts with `+`.
    * There is always a space between parameters.
    * Macros in the same file are tracked, and not included in parameter
    indentation.
    * `TEXT`, `DATA` and `GLOBL` and labels are level 0 indentation.
    * Aligns `\` in multiline macros in blocks.


    There is a standalone command, called `asmfmt`, with similar syntax as
    gofmt, which operates on ".s" assembler files. There are replacements
    for `gofmt`, `goreturns` and `goimports`, which also processes ".s"
    files when processing a package.

    I am looking for feedback before "locking" the format. When testing, you
    should of course back up your files.

    Does it do any stupid formatting? Does it break anything? Does it miss
    something?


    Thanks!

    /Klaus

    --
    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+unsubscribe@googlegroups.com
    For more options, visit https://groups.google.com/d/optout.

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Klaus Post at Dec 2, 2015 at 10:37 am

    On Wednesday, 2 December 2015 11:24:45 UTC+1, Nick Craig-Wood wrote:
    I had a go with it on https://github.com/ncw/iprime

    The complicated macros there, eg MOD_REDUCE with its token pasting seems
    to confuse it rather.

    That said, I just discovered that those files don't even compile with
    1.5 for reasons I haven't got time to work out just now, so maybe that
    isn't the best of tests!
    Thanks a bunch Nick - it nicely shows some issues that should be handled.
    Comment ordering seems to be a problem, and macro handling definitely needs
    improvement.

    It is a "dumb" parser, so, so it doesn't really matter if it compiles, it
    absolutely shouldn't create additional breakage, as it does now.


    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Klaus Post at Dec 2, 2015 at 2:41 pm
    Hi!

    Thanks to the fancy macro (ab)use in Nicks example, macros got a
    considerable update!

    * Block comments in macro definitions are handled much more conservatively.
    * Line continuation indentation is much more accurate.
    * Emacs integration documentation contributed by Bryan Bell.
    * Fixed case where block comments in line comments were not ignored.
    * Fixed some rare cases where tabs could slip through and create problems
    for indentation.
    * Fixed parameter length sometimes slightly off.

    @Nick, I suspect the issue is the labels that are generated by the
    pre-processor. The `label/**/1:` is a nice hack, but it depends on the
    block comments not being removed before macro parameters are inserted. My
    guess is that this changed at some time.


    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nick Craig-Wood at Dec 2, 2015 at 8:45 pm

    On 02/12/15 14:41, Klaus Post wrote:
    Thanks to the fancy macro (ab)use in Nicks example, macros got a
    considerable update! :-)
    * Block comments in macro definitions are handled much more conservatively.
    * Line continuation indentation is much more accurate.
    * Emacs integration documentation contributed by Bryan Bell.
    * Fixed case where block comments in line comments were not ignored.
    * Fixed some rare cases where tabs could slip through and create
    problems for indentation.
    * Fixed parameter length sometimes slightly off.

    @Nick, I suspect the issue is the labels that are generated by the
    pre-processor. The `label/**/1:` is a nice hack, but it depends on the
    block comments not being removed before macro parameters are inserted.
    My guess is that this changed at some time.
    That label/**/1 trick is how token pasting was done in pre-ANSI C. The
    ANSI C pre-processor replaced each comment with one space wrecking that
    trick. They did introduce label##1 for the purpose in ANSI C but
    unfortunately that doesn't seem to work in the Go assembler :-(

    I guess this might be considered a regression since these files used to
    assemble, and that change isn't mentioned in the release notes. Then
    again I don't think I saw anyone else using token pasting in assembler
    though!

    --
    Nick Craig-Wood <nick@craig-wood.com> -- http://www.craig-wood.com/nick

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Klaus Post at Dec 14, 2015 at 3:47 pm
    Hi!

    I have now upgraded the program to STABLE.

    https://github.com/klauspost/asmfmt


    This means that I don't expect to change anything unless bugs or bad corner
    cases show up, that only have a limited impact.

    Thanks for the great feedback!


    /Klaus

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 30, '15 at 3:44p
activeDec 14, '15 at 3:47p
posts17
users9
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase