From 968a2e4064c22d156a5a3373f7000ed56410c5fb Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 19 Aug 2020 04:06:29 +0000 Subject: [PATCH] Bug 1657135 - unify integer and floating-point argument allocation r=xpcom-reviewers,nika Through some sleight-of-hand, we can treat argument allocation in aarch64's xptcinvoke exactly the same for integer and floating-point arguments. This change isn't so important now, but it centralizes the allocation of stack slots, which is important for making this code handle Apple's calling conventions. Depends on D87005 Differential Revision: https://phabricator.services.mozilla.com/D87006 --- .../xptcall/md/unix/xptcinvoke_aarch64.cpp | 82 +++++++------------ 1 file changed, 30 insertions(+), 52 deletions(-) diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_aarch64.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_aarch64.cpp index 047bf45456af..3dd65f2a33a2 100644 --- a/xpcom/reflect/xptcall/md/unix/xptcinvoke_aarch64.cpp +++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_aarch64.cpp @@ -24,69 +24,47 @@ #endif /* - * Allocation of integer function arguments initially to registers r1-r7 - * and then to stack. Handling of 'that' argument which goes to register r0 - * is handled separately and does not belong here. + * Allocation of function arguments to their appropriate place in registers + * if possible and then to the stack. Handling of 'that' argument which + * goes to register r0 is handled separately and does not belong here. * - * 'ireg_args' - pointer to the current position in the buffer, - * corresponding to the register arguments - * 'stack_args' - pointer to the current position in the buffer, - * corresponding to the arguments on stack - * 'end' - pointer to the end of the registers argument - * buffer. + * Note that we are handling integer arguments and floating-point arguments + * identically, depending on which register area is passed to this function. + * + * 'reg_args' - pointer to the current position in the buffer, + * corresponding to the register arguments. + * 'reg_args_end' - pointer to the end of the registers argument + * buffer. + * 'stack_args' - pointer to the current position in the buffer, + * corresponding to the arguments on stack. + * 'data' - typed data to put on the stack. */ -static inline void alloc_word(uint64_t* &ireg_args, - uint64_t* &stack_args, - uint64_t* end, - uint64_t data) +template +static inline void alloc_arg(uint64_t* ®_args, + uint64_t* reg_args_end, + uint64_t* &stack_args, + T* data) { - if (ireg_args < end) { - *ireg_args = data; - ireg_args++; + if (reg_args < reg_args_end) { + memcpy(reg_args, data, sizeof(T)); + reg_args++; } else { - *stack_args = data; + memcpy(stack_args, data, sizeof(T)); + // Allocate a word-sized stack slot no matter what. stack_args++; } } -static inline void alloc_double(double* &freg_args, - uint64_t* &stack_args, - double* end, - double data) -{ - if (freg_args < end) { - *freg_args = data; - freg_args++; - } else { - memcpy(stack_args, &data, sizeof(data)); - stack_args++; - } -} - -static inline void alloc_float(double* &freg_args, - uint64_t* &stack_args, - double* end, - float data) -{ - if (freg_args < end) { - memcpy(freg_args, &data, sizeof(data)); - freg_args++; - } else { - memcpy(stack_args, &data, sizeof(data)); - stack_args++; - } -} - - extern "C" void invoke_copy_to_stack(uint64_t* stk, uint64_t *end, uint32_t paramCount, nsXPTCVariant* s) { uint64_t *ireg_args = stk; uint64_t *ireg_end = ireg_args + 8; - double *freg_args = (double *)ireg_end; - double *freg_end = freg_args + 8; - uint64_t *stack_args = (uint64_t *)freg_end; + // Pun on integer and floating-point registers being the same size. + uint64_t *freg_args = ireg_end; + uint64_t *freg_end = freg_args + 8; + uint64_t *stack_args = freg_end; // leave room for 'that' argument in x0 ++ireg_args; @@ -102,10 +80,10 @@ invoke_copy_to_stack(uint64_t* stk, uint64_t *end, // slots. switch (s->type) { case nsXPTType::T_FLOAT: - alloc_float(freg_args, stack_args, freg_end, s->val.f); + alloc_arg(freg_args, freg_end, stack_args, &s->val.f); continue; case nsXPTType::T_DOUBLE: - alloc_double(freg_args, stack_args, freg_end, s->val.d); + alloc_arg(freg_args, freg_end, stack_args, &s->val.d); continue; case nsXPTType::T_I8: word = s->val.i8; break; case nsXPTType::T_I16: word = s->val.i16; break; @@ -125,7 +103,7 @@ invoke_copy_to_stack(uint64_t* stk, uint64_t *end, } } - alloc_word(ireg_args, stack_args, ireg_end, word); + alloc_arg(ireg_args, ireg_end, stack_args, &word); } }