0

I've been thinking about writing some x86/64 assembly code in an open source project, for optimizing performance, however I can see compatibility issues if I want wide support:

  • different calling conventions across platforms
  • different syntax across compilers (MSVC (MASM) vs GCC/Clang (GAS))
  • haven't really looked into it, but would supporting PIC vs non-PIC be an issue?
  • 32/64-bit differences

What options are available if I don't want to write multiple copies of everything to target all combinations of the above? I figure that I may have to write separate 32/64-bit routines, which I can accept, but I'd like to avoid the others.

From what I've seen, there's no universal or widely accepted solution to this issue. Approaches I've seen:

  • some projects just seem to go the multiple copy route
  • OpenSSL has some Perl script which I guess transpiles the assembly to handle the differences
  • I've seen some projects which require the end user (the one building the source) have a separate assembler, like NASM installed, and then they use macros to deal with the calling convention differences

To make building easy, I'd prefer not require the end user have to install a separate assembler. A transpiling script/application sounds nice, but is there one which is not specific to a project (like OpenSSL), that is perhaps "widely used"?

I've been thinking about another option: go the macro route above, but assemble object files for the various combinations, and distribute that.

Or are there any other options?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Nyan
  • 641
  • 5
  • 9
  • 1
    *To make building easy, I'd prefer not require the end user have to install a separate assembler.* - that part's a duplicate of [Write x86 asm functions portably (win/linux/osx), without a build-depend on yasm/nasm?](https://stackoverflow.com/q/31734263). You probably want GAS syntax (either AT&T or `.intel_syntax noprefix`). All x86-64 dev environments except MSVC include an assembler for that syntax. With some macros you can maybe adapt for calling conventions, e.g. include some extra `push` and/or `mov` instructions at the top of functions for the Windows calling convention. – Peter Cordes Jun 07 '20 at 07:40
  • Some projects like x264 and x265 simply require NASM as a build dependency. It heavily uses macros to adapt to calling convention differences, including macros for register names. And to share code between 32 and 64-bit for functions that only need 8 or fewer XMM/YMM registers. There unfortunately aren't any really great solutions that don't require installing NASM or GAS on at least some machines. – Peter Cordes Jun 07 '20 at 07:43
  • I'd highly recommend just having a build dependency on NASM or GAS, instead of maintaining 2 copies of your asm. – Peter Cordes Jun 07 '20 at 07:44
  • Thanks for the comments. Unfortunately I *must* support MSVC (the (rather crap) build system only supports MSVC on Windows). I'm not sure if it even supports external assemblers (it's wired to specific compilers) - though that's something I could explore. I'm currently inclined to just ship object files. – Nyan Jun 07 '20 at 08:27
  • 1
    Yeah, it looks like a dupe of that question - didn't find that despite all my searching. Although it doesn't seem to have a satisfactory answer unfortunately. I'm still interested in the consensus of just shipping object files though, which wasn't suggested. – Nyan Jun 07 '20 at 08:41

0 Answers0