ARM aapcs calling convention for small vectors

Hi all,

I was wondering if ARM aapcs calling convention defines how to pass small vectors as parameter to a routine.
By small vectors, I mean with size less than a 32-bit integer. For instance if we consider following code:

; ModuleID = 'smallvect.ll'
define arm_aapcscc void @foo(<2 x i8>* %p) {
L.entry:
    %0 = load <2 x i8>* %p
    call arm_aapcscc void @bar(<2 x i8> %0)
    ret void
}

declare arm_aapcscc void @bar(<2 x i8> %a)

and we compile it using llc -march=arm -mcpu=cortex-a9 we got following assembly generated:

...
foo: @ @foo
@ BB#0: @ %L.entry
  push {lr}
  vld1.16 {d16[0]}, [r0, :16]
  vmovl.u8 q8, d16
  vmovl.u16 q8, d16
  vmov r0, r1, d16
  bl bar
  pop {lr}
  bx lr
.Ltmp0:
  .size foo, .Ltmp0-foo
...

Hi and Low part of vector is passed to bar using r0, r1 register. I was thinking that only r0 could have been used since size of vector is 16-bits.
So is this behavior occuring because vector argument passing might not have been defined in ARM aapcs ?

Thanks for your answers
Seb

I was wondering if ARM aapcs calling convention defines how to pass small vectors as parameter to a routine.
By small vectors, I mean with size less than a 32-bit integer.

The AAPCS is silent on the matter. Vectors with size <= 32 aren't
recognised by the PCS so a language wanting to support them with
well-defined semantics (including LLVM) is expected to choose and
specify which machine types they map to (and how!). This is much like
how the C++ ABI specifies how its types map onto PCS-level ones.

I doubt LLVM has made an active choice on this though; it's probably
just relying on default behaviour being good enough to make it work.

Tim.

Though, this piece of code could be smarter than that. Patches welcome! :wink: