Skip to content
Snippets Groups Projects

Fix #96: Make x86 disassem produce code usable by gcc/clang

We make the x86 disassembler produce code that can (almost) be directly used by gcc or clang to produce the same code as produced by the compiler.

This means:

  1. Make the disassembler print the radix indicator ("#x") by default.
  2. Add ".intel_syntax noprefix" to tell gcc/clang the syntax being used. This is added only for x86.
  3. Use /* ... */ for comments instead of ;. This is done for all archs. We also set *print-right-margin* to 100 so that we're less likely to wrap long things, or truncate the output.
  4. Increase *note-column* for x86 because some instructions can be rather long; this makes the note columns more likely to line up neatly without having some instructions pushing the note column farther right so that they don't line up neatly.

This doesn't solve everything; we still have an issue with printing call in a way that's accepted by both clang and gcc and so that both clang and gcc produce the same code.

Edited by Raymond Toy

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Here's an example of the output for the function

    (defun bar (x)
      (declare (double-float x))
      (sin x))
    6004df40:       .intel_syntax noprefix
                    .entry |BAR|(x)                       /* (function (double-float)
                                                              (double-float -1.0d0 1.0d0)) */
        df58:       pop       dword ptr [ebp-#x8]
        df5b:       lea       esp, [ebp-#x40]
    
        df5e:       cmp       ecx, #x4                    /* [:non-local-entry] */
        df61:       jne       L3
        df67:       mov       eax, edx
        df69:       and       eax, #x7
        df6c:       cmp       eax, #x7
        df6f:       jne       L5
        df75:       movzx     eax, byte ptr [edx-#x7]
        df79:       cmp       eax, #x16
        df7c:       jne       L5
        df82:       movsd     xmm0, [edx+#x1]
        df87:       movsd     [ebp-#x1c], xmm0
    
        df8c:       lea       eax, [#x5f000048]           /*  fdlibm_sin */
                                                          /* No-arg-parsing entry point */
                                                          /* [:non-local-entry] */
        df92:       sub       esp, #x8
        df95:       and       esp, #xfffffff0
        df9b:       movsd     xmm0, [ebp-#x1c]
        dfa0:       movsd     [ebp-#x24], xmm0
        dfa5:       movsd     xmm0, [ebp-#x24]
        dfaa:       movsd     [esp], xmm0
        dfaf:       call      eax
    
    /* [6] (SIN X) */
    
        dfb1:       fstp      qword ptr [ebp-#x14]        /* [:internal-error] */
        dfb4:       movsd     xmm0, [ebp-#x14]
        dfb9:       add       esp, #x8
    
        dfbc:       mov       byte ptr [#x28000234], #x0  /* lisp::*pseudo-atomic-interrupted* */
                                                          /* [:block-start] */
        dfc3:       mov       byte ptr [#x2800021c], #x4  /* lisp::*pseudo-atomic-atomic* */
        dfca:       mov       edx, #x10
        dfcf:       add       edx, dword ptr [#x28000384] /* x86::*current-region-free-pointer* */
        dfd5:       cmp       edx, dword ptr [#x2800039c] /* x86::*current-region-end-addr* */
        dfdb:       jbe       L0
        dfdd:       sub       edx, dword ptr [#x28000384] /* x86::*current-region-free-pointer* */
        dfe3:       push      eax
        dfe4:       mov       eax, edx
        dfe6:       call      #x5f000008                  /*  alloc_overflow_sse2 */
        dfeb:       mov       edx, eax
        dfed:       pop       eax
        dfee:       jmp       L1
        dff0: L0:   xchg      edx, dword ptr [#x28000384] /* x86::*current-region-free-pointer* */
        dff6: L1:   mov       dword ptr [edx], #x316
        dffc:       lea       edx, [edx+#x7]
        dfff:       movsd     [edx+#x1], xmm0
        e004:       mov       byte ptr [#x2800021c], #x0  /* lisp::*pseudo-atomic-atomic* */
        e00b:       cmp       byte ptr [#x28000234], #x0  /* lisp::*pseudo-atomic-interrupted* */
        e012:       je        L2
        e014:       ud1       ecx, ecx                    /* Trap 9: Pending interrupt trap */
        e017: L2:   mov       ecx, dword ptr [ebp-#x8]
        e01a:       mov       eax, dword ptr [ebp-#x4]
        e01d:       add       ecx, #x2
        e020:       mov       esp, ebp
        e022:       mov       ebp, eax
        e024:       jmp       ecx
        e026:       nop
        e027:       nop
        e028:       nop
        e029:       nop
        e02a:       nop
        e02b:       nop
        e02c:       nop
        e02d:       nop
        e02e:       nop
        e02f:       nop
        e030: L3:   ud1       ecx, edx                    /* Trap 10: Error trap */
        e033:       .byte     #x02
        e034:       .byte     #x1a                        /* INVALID-ARGUMENT-COUNT-ERROR */
        e035:       .byte     #x4f                        /* ECX */
        e036: L4: L5:ud1      ecx, edx                    /* Trap 10: Error trap */
        e039:       .byte     #x02
        e03a:       .byte     #x06                        /* OBJECT-NOT-DOUBLE-FLOAT-ERROR */
        e03b:       .byte     #x90                        /* EDX */
  • Raymond Toy added 1 commit

    added 1 commit

    Compare with previous version

  • Raymond Toy added 1 commit

    added 1 commit

    • 44ffc34a - Increase *note-column* for x86

    Compare with previous version

  • Raymond Toy changed the description

    changed the description

  • Raymond Toy changed the description

    changed the description

  • Raymond Toy added 1 commit

    added 1 commit

    • 8b738bbe - Disassemble call with OFFSET

    Compare with previous version

  • Raymond Toy marked this merge request as ready

    marked this merge request as ready

  • Raymond Toy added 1 commit

    added 1 commit

    • c9feabf9 - Add comment about printer for call inst

    Compare with previous version

  • mentioned in issue #185 (closed)

  • Raymond Toy mentioned in merge request !138 (merged)

    mentioned in merge request !138 (merged)

  • Raymond Toy mentioned in issue #188

    mentioned in issue #188

  • assigned to @rtoy

  • Raymond Toy requested review from @cshapiro

    requested review from @cshapiro

      1. Make the disassembler print the radix indicator ("#x") by default.

      The presence of the Lisp style radix indication will cause a syntax error. You can use a 0x prefix or a h suffix but not a #x suffix

      6004df40: .intel_syntax noprefix

      The presence of the address cause a syntax error

      .entry |BAR|(x)

      This invalid directive will cause an error

      dff0: L0: xchg edx, dword ptr [#x28000384] /* x86::*current-region-free-pointer* */

      For the sake of the compiler this should be .L0 on Linux and L0 on Darwin to indicate a local label.

      ...

      All that aside, the default disassembly output should foremost be for human consumption. Being able to feed this into a compiler is a very laudable goal but to get there from here you are going need to either post-process the output you are generating today or put this behind a flag that disassembles for machine consumption adding all of the needed context in the output a like the constant vector or symbols like T and NIL. To make this amenable to the compiler we will need to specify .text and .data or the ELF type information which you would need for assembling.

      Since that extra step is needed why burden humans with changes like renaming ; to /* ... */ and add things like .intel_sytnax noprefix when that is readily done by a post-processing program or it can be pushed behind a flag? Moreover, a script could automate all of the work to create a .S file that the user can compile without having to know all of the details of what is needed to host code like this outside of a real Lisp.

    • Good points. Then I think the only thing I want to do is change the default to print the (Lisp) radix marker by default. (You can already do this via disassem:disassemble, but I think disassemble should print the radix marker too.

      Also I'd like to move the note column out a bit on x86 because some instructions extend past that column.

      I do have a partial implementation of a script to convert the disassembly to something that gcc or clang will mostly like. I'll add it to the snippets section.

    • I think it would be absolutely wonderful to show some kind of radix indicator for hexadecimal constants. That ambiguity has annoyed me for years.

    • Ok, I'm going to close this MR and the corresponding issue and file a new one stating saying we're just adding the marker (and the note-column change).

    • Please register or sign in to reply
  • closed

  • mentioned in issue #96 (closed)

Please register or sign in to reply
Loading