0

I have the following test program to examine the code generated by GCC. rotlFixed is provided in the header misc.h, and its declared as inline. It also uses a template specialization to invoke GCC inline assembly:

int main(int argc, char* argv[])
{
  byte r1 = rotlFixed(1, 1);
  byte r2 = rotlFixed(1, 255);

  word16 r3 = rotlFixed(1, 1);
  word16 r4 = rotlFixed(1, 255);
  word16 r5 = rotlFixed(1, 256);
  word16 r6 = rotlFixed(1, 65535);

  cout << r1 << "," << r2 << "," << r3 << "," << r4 << ",";
  cout << r5 << "," << r6 << endl;

  return 0;
}

According to How to get GCC to generate assembly code, I compiled the source file with:

g++ -O1 -S -c cryptopp-test.cxx

But when I cat, I don't see the call to the rotates:

$ cat cryptopp-test.s
    .file   "cryptopp-test.cxx"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "misc.h"
.LC1:
    .string "y < THIS_SIZE"
    .text
    .globl  main
    .type   main, @function
main:
.LFB2196:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $_ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__, %ecx
    movl    $692, %edx
    movl    $.LC0, %esi
    movl    $.LC1, %edi
    call    __assert_fail
    .cfi_endproc
.LFE2196:
    .size   main, .-main
    .type   _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB2311:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $_ZStL8__ioinit, %edi
    call    _ZNSt8ios_base4InitC1Ev
    movl    $__dso_handle, %edx
    movl    $_ZStL8__ioinit, %esi
    movl    $_ZNSt8ios_base4InitD1Ev, %edi
    call    __cxa_atexit
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE2311:
    .size   _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
    .section    .init_array,"aw"
    .align 8
    .quad   _GLOBAL__sub_I_main
    .section    .rodata
    .align 32
    .type   _ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__, @object
    .size   _ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__, 54
_ZZN8CryptoPP9rotlFixedIiEET_S1_jE19__PRETTY_FUNCTION__:
    .string "T CryptoPP::rotlFixed(T, unsigned int) [with T = int]"
    .local  _ZStL8__ioinit
    .comm   _ZStL8__ioinit,1,1
    .hidden __dso_handle
    .ident  "GCC: (GNU) 5.1.1 20150618 (Red Hat 5.1.1-4)"
    .section    .note.GNU-stack,"",@progbits

I'm obviously doing something wrong because the calls I want to inspect are missing.

How do I generate the listing? Or, if I am generating it, how do I display all relevant parts?

Thanks in advance.


In case it matters, the system is Fedora 22 x86_64, and GCC 5.1.1:

$ uname -a
Linux localhost.localdomain 4.0.4-301.fc22.x86_64 #1 SMP Thu May 21 13:10:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)
...

Related, here's the underlying question that's causing me to want to look at the generated code How to force const propagation through an inline function?

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885

4 Answers4

2

It looks like g++ has optimized your main() to a failure of an assertion that "y < THIS_SIZE"

If you want more information, you should show us the implementation of rotlFixed().

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • Oh, that's interesting. Let me add the code, then. The base template code utilizes the assert. The specializations use inline assembly without the assert and is guarded by a `__GNU_C__`. – jww Jul 19 '15 at 04:00
  • 1
    As far as I know, `__GNU_C__` will not be defined - I think you want to use `__GNUC__` – Michael Burr Jul 19 '15 at 04:05
  • *"As far as I know, `__GNU_C__` will not be defined..."* - My bad... I just diff'd the source - its `__GNUC__`. Yes, I'm a Maryland grad and fan. I tried to redshirt for football back in the mid-1980s. Man, those guys hit too hard... – jww Jul 19 '15 at 04:20
1

The flag -O1 is optimizing away your function call rotlFixed(...). Do it with -O0.

Also, you don't need -c if you've using -S.

Roshan Mathews
  • 5,788
  • 2
  • 26
  • 36
  • Part of what I am validating is selection of a template specialization that uses inline assembler. At -O0, the specialized function is ***not*** selected because the compiler does not propagate `static const` values into assembly that has `immediate` constraints. – jww Jul 19 '15 at 04:02
1

If you'd like to see the machine code after compiler optimization, put it into a file without main() and compile it. Then the compiler will think it is building a function to be called from somewhere else.

With the way that you have it all in main() the compiler sees that you never use the results and discards the unused functions.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
1

You really want to pass -fverbose-asm to g++ or gcc with -S and -O.

You probably want to also get the preprocessed form (with gcc -C -E) of your code.

The -fverbose-asm asks the GCC compiler to emit comments in the generated assembler code.

You obviously need some optimization -O1 at least; otherwise the generated assembler would contain a lot of useless code (making it less readable).

You might want to pass -fdump-tree-all (or other -fdump flags) to get hundreds of dump files describing the various internal representations inside GCC.

You could use MELT to customize GCC.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547