[aarch64-port-dev ] Optimize pushes and pops

Edward Nevill ed at camswl.com
Mon May 12 19:18:19 UTC 2014


On Mon, 2014-05-12 at 19:42 +0100, Andrew Haley wrote:
> On 05/12/2014 05:33 PM, Andrew Haley wrote:
>   0x00007fffd10d2030: ldp	x1, x2, [sp]
>   0x00007fffd10d2034: ldp	x3, x4, [sp,#16]
>   0x00007fffd10d2038: ldp	x5, x6, [sp,#32]
>   0x00007fffd10d203c: add	sp, sp, #0x30
> 
> Andrew.
> 

What about

 ldp x3, x4, [sp, #16]
 ldp x5, x6, [sp, #32]
 ldp x1, x2, [sp], #48

Is this better or worse?

Do we need to keep a count of words_pushed? This must == count at the end. If in doubt, assert(words_pushed == count, ...) and return count. See below:-

Regards,
Ed.


--- CUT HERE ---
int MacroAssembler::push(unsigned int bitset, Register stack) {
  // need to push all registers including original sp

  int words_pushed = 0;

  // Scan bitset to accumulate register pairs
  unsigned char regs[32];
  int count = 0;
  for (int reg = 0; reg <= 30; reg++) {
    if (1 & bitset)
      regs[count++] = reg;
    bitset >>= 1;
  }
  regs[count++] = zr->encoding_nocheck();
  count &= ~1;  // Only push an even nuber of regs

  if (count) {
    stp(as_Register(regs[0]), as_Register(regs[1]),
       Address(pre(stack, -count * wordSize)));
    words_pushed += 2;
  }
  for (int i = 2; i < count; i += 2) {
    stp(as_Register(regs[i]), as_Register(regs[i+1]),
       Address(stack, i * wordSize));
    words_pushed += 2;
  }
  assert(words_pushed == count, "oops, pushed != count");
  
  return count;
} 

int MacroAssembler::pop(unsigned int bitset, Register stack) {
  int words_pushed = 0;
  
  // Scan bitset to accumulate register pairs
  unsigned char regs[32];
  int count = 0;
  for (int reg = 0; reg <= 30; reg++) {
    if (1 & bitset)
      regs[count++] = reg;
    bitset >>= 1;
  }
  regs[count++] = zr->encoding_nocheck();
  count &= ~1;
  
  for (int i = 2; i < count; i += 2) {
    ldp(as_Register(regs[i]), as_Register(regs[i+1]),
       Address(stack, i * wordSize));
    words_pushed += 2;
  }
  if (count) {
    ldp(as_Register(regs[0]), as_Register(regs[1]),
       Address(post(stack, count * wordSize)));
    words_pushed += 2;
  }  
  assert(words_pushed == count, "oops, pushed != count");


  return count;
}
--- CUT HERE ---




More information about the aarch64-port-dev mailing list