0

I am working on a project using AltiVec programming interface.

In one place I want to store 8 bytes from a vector register to a buffer.

In SSE, we have an intrinsic _mm_storel_epi64 to store lower 8 bytes of a SIMD register to a buffer.

Any ideas on implementing 8 byte store in AltiVec?

Paul R
  • 208,748
  • 37
  • 389
  • 560
sunmoon
  • 1,448
  • 1
  • 15
  • 27

2 Answers2

1

I think the only way to do this with AltiVec is:

- load 16 bytes containing 8 byte destination buffer (`vec_ld`)
- mask in the 8 bytes you want to write (`vec_sel`)
- store the modified 16 byte vector (`vec_st`)

This assumes that the required 8 byte destination falls within a 16 byte aligned vector of course. For example, suppose the destination address is 0x1004, then you would load from address 0x1000, modify bytes 4..11, then write the vector back to 0x1000.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • I wanted to do unaligned store. – sunmoon Feb 10 '15 at 09:28
  • You didn't actually mention this in the question, but so long as the destination 8 bytes lie within an aligned 16 byte range then the above approach still works. If the 8 byte destination lies across a 16 byte boundary then you'll have to do a little more work. – Paul R Feb 10 '15 at 09:29
  • vec_st aligns the pointer passed and stores the vector register. I might over ride the data that i am not intended to do so. with vec_st. – sunmoon Feb 10 '15 at 09:32
  • Yes, I know - read what I wrote in the comment above - use an aligned address that includes the required 8 bytes. I've added further explanation to the answer above now. – Paul R Feb 10 '15 at 09:32
0

I have found one way to store the 8 bytes to store to an unaligned address.

Following is the program.

The following program stores the first 8 bytes of vector on to buf. k - I have used as the variable to change the location in the buf to store the data

int main(int argc, char *argv[])
{
    unsigned char buf[40];
    vector unsigned char res;
    vector unsigned char on = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

    memset(buf, 0, 40);

    int k = atoi(argv[1]);

    unsigned char *outp = &(buf[k]);

    res =  vec_perm( on, on, vec_lvsr(0, (unsigned char *)outp);

    vec_ste( (vector unsigned char)res, 0, (unsigned char *)outp);

    vec_ste( (vector unsigned short)res, 1, (unsigned short *)outp);

    vec_ste( (vector unsigned short)res, 2, (unsigned short *)outp);

    vec_ste( (vector unsigned short)res, 4,  (unsigned short *)outp);

    vec_ste( (vector unsigned short)res, 6, (unsigned short *)outp);

    vec_ste( (vector unsigned char)res, 7, (unsigned char *)outp);

    print(buf);

}
Paul R
  • 208,748
  • 37
  • 389
  • 560
sunmoon
  • 1,448
  • 1
  • 15
  • 27