1

I'm building Botan on Solaris 11.3 with the SunCC compiler that comes with Developer Studio 12.5. I'm not too familiar with the library or Solaris, and it takes me some effort to track down issues.

The compile is dying on a relatively benign file called divide.cpp. I've got it reduced to the following test case. According to Oracle's GCC-style asm inlining support in Sun Studio 12 compilers, the ASM is well formed. Clang, GCC and ICC happily consume the code.

$ /opt/developerstudio12.5/bin/CC -m64 -std=c++11 test.cxx -c
"test.cxx", [main]:ube: error: Invalid reference to argument '1' in GASM Inlining
CC: ube failed for test.cxx

$ cat test.cxx
#include <iostream>
#include <stdint.h>    
typedef uint64_t word;

inline word multadd(word a, word b, word* c)
{
    asm(
        "mulq %[b]          \n\t"
        "addq %[c],%[a]     \n\t"
        "adcq $0,%[carry]   \n\t" 

      : [a]"=a"(a), [b]"=rm"(b), [carry]"=&d"(*c)
      : "0"(a), "1"(b), [c]"g"(*c) : "cc");

   return a;
}

int main(int argc, char* argv[])
{
    word a, b, c, d;
    std::cin >> a >> b >> c;

    d = multadd(a, b, &c);

    return 0;
}

I can't find useful information on the error string Invalid reference to argument 'N' in GASM Inlining. I found sunCC chokes on inline assembler on the Oracle boards. But the answer is UBE is buggy and buy a support contract to learn more.

I have three questions:

  • What does the error message indicate?

  • How can I get SunCC to provide a source file and line number?

  • How can I work around the issue?


If I change the b parameter to just =m, then the same error is produced. If I change the b parameter to just =r, then a different error is generated:

asm(
    "mulq %[b]          \n\t"
    "addq %[c],%[a]     \n\t"
    "adcq $0,%[carry]   \n\t"

    : [a]"=a"(a), [b]"=r"(b), [carry]"=&d"(*c)
    : "0"(a), "1"(b), [c]"g"(*c) : "cc");

And the result:

$ /opt/developerstudio12.5/bin/CC  -m64 -std=c++11 test.cxx -c
Assembler: test.cxx
        "<null>", line 205 : Invalid instruction argument
        Near line: "mulq %rcx          "
        "<null>", line 206 : Invalid instruction argument
        Near line: "    addq %rbx,%rax     "
        "<null>", line 207 : Invalid instruction argument
        Near line: "    adcq $0,%rdx   "
CC: ube failed for test.cxx
jww
  • 97,681
  • 90
  • 411
  • 885
  • If this were gcc, I'd suggesting building using `-S`. It [looks like](https://docs.oracle.com/cd/E19205-01/819-5265/6n7c29df6/index.html#6n7c29dmc) Suncc may support this too? Seeing exactly what is getting generated would really help here. I also wonder about using `mull` and `addl`. That last `l` is supposed to indicate a 4byte int, but you are passing (what I assume are 2 byte) words? And that blog link you provided says that Sun's C++ doesn't handle 'immediate' operands well. `g` could mean `i`. Don't see how that's "argument 1" though. – David Wohlferd Jan 26 '17 at 00:46
  • The smaller case helps. Can you make it even smaller? What about using `""` for the asm string? My guess is that it will turn out that you need at least `mull %[b]`. – David Wohlferd Jan 26 '17 at 01:41
  • Since the problem occurs during the compile, it shouldn't actually be necessary for the blocks to work or produce the same result. Once you have trimmed down the needed asm to the minimum that still produces the error, you can start dropping arguments. I'm expecting: `asm("mull %[b]" : [b]"=rm"(b) : "0"(b));`. – David Wohlferd Jan 26 '17 at 01:57
  • Huh. I just sent you an email the other day about vector extract. IAC, the problem is clear from your most recent post: `mull %rcx` is an invalid statement. It is strange for several reasons: 1) `mull` (targets 32bit values) and cannot work with `rcx` (64bit value). 2) Why would it use rcx (instead of cx) if we are dealing with `words`? 3) Why is this section of code being executed at all? When you originally posted it, I thought you posted the section from `BOTAN_MP_USE_X86_32_ASM`, not `BOTAN_MP_USE_X86_64_ASM`. Which are you intending to target? – David Wohlferd Jan 26 '17 at 02:38
  • Maybe change `mull %[b]` to `mulw %w[b]`? – David Wohlferd Jan 26 '17 at 02:40
  • Actually, the BOTAN_MP_USE_X86_32_ASM vs BOTAN_MP_USE_X86_64_ASM is probably the key here. Somehow it is building for 64bit (as evidenced by emitting rcx), but thinks it is building 32bit (as evidenced by building the BOTAN_MP_USE_X86_32_ASM code). That kind of confusion can't end well. – David Wohlferd Jan 26 '17 at 02:53
  • @DavidWohlferd - I fixed the example to use quad words. Same result. – jww Jan 26 '17 at 03:12

1 Answers1

1

What does the error message indicate?

Unfortunately, no idea.

If someone buys a support contract and has the time, then please solicit Oracle for an answer .

How can I get SunCC to provide a source file and line number?

Unfortunately, no idea.

How can I work around the issue?

David Wohlferd suspected the [b]"=rm"(b) output operand. It looks like the one ASM block needs to be split into two blocks. Its an awful hack, but we have not figured out another way to do it.

inline word multadd(word a, word b, word* c)
{
    asm(
      "mulq %[b]            \n\t"

      : [a]"+a"(a), [b]"=&d"(b)
      : "0"(a), "1"(b));
    asm(
      "addq %[c],%[a]"      \n\t"
      "adcq $0,%[carry]     \n\t"

      : [a]"=a"(a), [carry]"=&d"(*c)
      : "a"(a), "d"(b), [c]"g"(*c) : "cc");

    return a;
}
jww
  • 97,681
  • 90
  • 411
  • 885