Reputation: 102296
I'm trying to compile a source file on PPC64-LE. I'm using the xlC compiler and the compile is failing. GCC accepts the program, so I'm not really sure what the cause of the problems are.
Here's the command line:
$ xlc test-p8.c -qarch=pwr8 -qaltivec -o test-p8.exe
Here's the compile error:
"test-p8.c", line 113.52: 1506-324 (S) "int" cannot be converted to "vector unsigned int".
"test-p8.c", line 120.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 121.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 122.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 123.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 124.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 125.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 126.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 127.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 128.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 130.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
Here's the relevant part of the source file. The source file is a reduced case for another problem, and it its available on GitHub.
$ cat -n test-p8.c
...
12 typedef unsigned char uint8_t;
13 typedef unsigned long long uint64_t;
14 typedef vector unsigned char uint8x16_p8;
15 typedef vector unsigned int uint64x2_p8;
...
76 __attribute__((aligned(16)))
77 uint8_t ks[176] = {
78 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x9, 0xcf, 0x4f, 0x3c,
...
89 };
...
113 uint64x2_p8 block = (uint64x2_p8)vec_vsx_ld(0U, (const uint8_t*)plain);
...
118 block = vec_xor(block, (uint64x2_p8)vec_ld(0U, (const uint8_t*)ks));
...
120 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 16U, (const uint8_t*)ks));
121 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 32U, (const uint8_t*)ks));
122 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 48U, (const uint8_t*)ks));
123 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 64U, (const uint8_t*)ks));
124 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 80U, (const uint8_t*)ks));
125 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 96U, (const uint8_t*)ks));
126 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld(112U, (const uint8_t*)ks));
127 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld(128U, (const uint8_t*)ks));
128 block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld(144U, (const uint8_t*)ks));
129
130 block = __builtin_crypto_vcipherlast(block, (uint64x2_p8)vec_ld(160U, (const uint8_t*)ks));
__builtin_crypto_vcipher
is a GCC built-in, and IBM states xlC supports it.
Line 118 is like all the other lines show above, but it does not trigger a warning or error.
What is the problem, and how do I fix it?
Upvotes: 2
Views: 310
Reputation: 361
On PPC64-LE, a lot of effort went into unifying the interface for the vector builtins between GCC and XL. The two teams worked together on adding a consistent interface to the ABI document. You can find it here:
The new vcipher function that's part of the ABI is vec_cipher_be, which xlC supports.
Note that part of the reason for the new function is that the types accepted by the some of the old GCC crypto functions would have endianess issues.
Upvotes: 2
Reputation: 678
The redbook you linked to is about "Performance Optimization and Tuning Techniques for IBM Power Systems Processors Including IBM POWER8" and is not compiler specific. It includes information about compiler support on POWER8, including the XLC and GCC compilers.
In section 7.3.1, page 149 of the redbook (page 171 if you're using the PDF page advancer), the following support is stated:
vector unsigned long long __builtin_crypto_vcipher (vector unsigned long long, vector unsigned long long)
vector unsigned char __vcipher (vector unsigned char, vector unsigned char)
If you're compiling with GCC, you should use __builtin_crypto_vcipher
, and if you're compiling with XLC, you should use __vcipher
.
Upvotes: 1
Reputation: 102296
Operation between types "vector unsigned int" and "int" is not allowed
I think I tracked this down. xlC does not know the function __builtin_crypto_vcipher
, so the compiler assumes the function accepts int
's as arguments or returns an int
(I'm not sure which at the moment). I believe the equivalent GCC message is something about a missing declaration and assuming an int
return.
Later, the unknown function takes a vector instead of an int:
__builtin_crypto_vcipher(block, ...)
or, it assigns an int
to a vector:
block = __builtin_crypto_vcipher(...)
When I switched to xlC's builtin __vcipher
the issue went away.
I don't know why the docs state xlC accepts GCC builtin's.
Upvotes: 0