D
David Mathog
I am trying to force the compiler to be sloppy with types to allow 16
byte chunks of
memory to be accessed in some places as in int, and in others as a
char, and so forth.
Mixed in with this is the gcc vector extension, but I don't think that
is the problem.
Here is a bit of sample code
8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* assumes int/uint are 4 bytes, ll/ull are 8*/
typedef union {
int v __attribute__ ((__vector_size__ (16)));
int a[4];
unsigned int u[4];
long long l[2];
unsigned long long U[2];
}__av4si;
typedef long long __m128i __attribute__ ((__vector_size__ (16),
__may_alias__));
int main(void){
int i,j;
int array[4]={1,2,4,8};
#ifdef BAD
__m128i result;
#else
__av4si result;
#endif
memcpy((void*)&result,&array[0],16);
for(j=0;j<4;j++){
i=((__av4si)result).a[j];
(void) fprintf(stdout, "A[%d] is %X\n",j,i);
}
}
8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<
# gcc -o short short.c
# ./short
A[0] is 1
A[1] is 2
A[2] is 4
A[3] is 8
# gcc -DBAD -o short short.c
short.c: In function 'main':
short.c:28: error: cast to union type from type not present in union
And there's the problem. The __m128i type is a sort of generic bag
for holding 16 bytes
of data, but I need a way to force it to be interpreted different
ways. Unfortunately in the many
functions which use it, none of which I can change, __m128i variables
are always passed by value. I am looking for a way to tell the
compiler to access it as in the example above, that is, without having
to resort to doing something like using memcpy to pull the data into
an array of the appropriate type. The only other approach that I have
come up with so far that works is:
i=(*((__av4si *)(&result))).a[j];
which is pretty hideous. In fact, if one has to resort to making
pointers and then changing the type that way the typedef union isn't
needed at all:
i=((int *)&result)[j];
Both of the last forms work when compiled with or without -DBAD. Is
there a cast syntax
more like this
i=((__av4si)result).a[j];
that is, no "&" employed, that will compile if "result" is an __m128i
variable?
Thanks,
David Mathog
byte chunks of
memory to be accessed in some places as in int, and in others as a
char, and so forth.
Mixed in with this is the gcc vector extension, but I don't think that
is the problem.
Here is a bit of sample code
8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* assumes int/uint are 4 bytes, ll/ull are 8*/
typedef union {
int v __attribute__ ((__vector_size__ (16)));
int a[4];
unsigned int u[4];
long long l[2];
unsigned long long U[2];
}__av4si;
typedef long long __m128i __attribute__ ((__vector_size__ (16),
__may_alias__));
int main(void){
int i,j;
int array[4]={1,2,4,8};
#ifdef BAD
__m128i result;
#else
__av4si result;
#endif
memcpy((void*)&result,&array[0],16);
for(j=0;j<4;j++){
i=((__av4si)result).a[j];
(void) fprintf(stdout, "A[%d] is %X\n",j,i);
}
}
8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<8<
# gcc -o short short.c
# ./short
A[0] is 1
A[1] is 2
A[2] is 4
A[3] is 8
# gcc -DBAD -o short short.c
short.c: In function 'main':
short.c:28: error: cast to union type from type not present in union
And there's the problem. The __m128i type is a sort of generic bag
for holding 16 bytes
of data, but I need a way to force it to be interpreted different
ways. Unfortunately in the many
functions which use it, none of which I can change, __m128i variables
are always passed by value. I am looking for a way to tell the
compiler to access it as in the example above, that is, without having
to resort to doing something like using memcpy to pull the data into
an array of the appropriate type. The only other approach that I have
come up with so far that works is:
i=(*((__av4si *)(&result))).a[j];
which is pretty hideous. In fact, if one has to resort to making
pointers and then changing the type that way the typedef union isn't
needed at all:
i=((int *)&result)[j];
Both of the last forms work when compiled with or without -DBAD. Is
there a cast syntax
more like this
i=((__av4si)result).a[j];
that is, no "&" employed, that will compile if "result" is an __m128i
variable?
Thanks,
David Mathog