xpcom/reflect/xptcall/src/md/unix/xptcinvoke_aarch64.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /* Platform specific code to invoke XPCOM methods on native objects */
michael@0 7
michael@0 8 #include "xptcprivate.h"
michael@0 9
michael@0 10 #if !defined(__aarch64__)
michael@0 11 #error "This code is for Linux AArch64 only."
michael@0 12 #endif
michael@0 13
michael@0 14
michael@0 15 /* "Procedure Call Standard for the ARM 64-bit Architecture" document, sections
michael@0 16 * "5.4 Parameter Passing" and "6.1.2 Procedure Calling" contain all the
michael@0 17 * needed information.
michael@0 18 *
michael@0 19 * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
michael@0 20 */
michael@0 21
michael@0 22 #ifndef __AARCH64EL__
michael@0 23 #error "Only little endian compatibility was tested"
michael@0 24 #endif
michael@0 25
michael@0 26 /*
michael@0 27 * Allocation of integer function arguments initially to registers r1-r7
michael@0 28 * and then to stack. Handling of 'that' argument which goes to register r0
michael@0 29 * is handled separately and does not belong here.
michael@0 30 *
michael@0 31 * 'ireg_args' - pointer to the current position in the buffer,
michael@0 32 * corresponding to the register arguments
michael@0 33 * 'stack_args' - pointer to the current position in the buffer,
michael@0 34 * corresponding to the arguments on stack
michael@0 35 * 'end' - pointer to the end of the registers argument
michael@0 36 * buffer.
michael@0 37 */
michael@0 38 static inline void alloc_word(uint64_t* &ireg_args,
michael@0 39 uint64_t* &stack_args,
michael@0 40 uint64_t* end,
michael@0 41 uint64_t data)
michael@0 42 {
michael@0 43 if (ireg_args < end) {
michael@0 44 *ireg_args = data;
michael@0 45 ireg_args++;
michael@0 46 } else {
michael@0 47 *stack_args = data;
michael@0 48 stack_args++;
michael@0 49 }
michael@0 50 }
michael@0 51
michael@0 52 static inline void alloc_double(double* &freg_args,
michael@0 53 uint64_t* &stack_args,
michael@0 54 double* end,
michael@0 55 double data)
michael@0 56 {
michael@0 57 if (freg_args < end) {
michael@0 58 *freg_args = data;
michael@0 59 freg_args++;
michael@0 60 } else {
michael@0 61 memcpy(stack_args, &data, sizeof(data));
michael@0 62 stack_args++;
michael@0 63 }
michael@0 64 }
michael@0 65
michael@0 66 static inline void alloc_float(double* &freg_args,
michael@0 67 uint64_t* &stack_args,
michael@0 68 double* end,
michael@0 69 float data)
michael@0 70 {
michael@0 71 if (freg_args < end) {
michael@0 72 memcpy(freg_args, &data, sizeof(data));
michael@0 73 freg_args++;
michael@0 74 } else {
michael@0 75 memcpy(stack_args, &data, sizeof(data));
michael@0 76 stack_args++;
michael@0 77 }
michael@0 78 }
michael@0 79
michael@0 80
michael@0 81 extern "C" void
michael@0 82 invoke_copy_to_stack(uint64_t* stk, uint64_t *end,
michael@0 83 uint32_t paramCount, nsXPTCVariant* s)
michael@0 84 {
michael@0 85 uint64_t *ireg_args = stk;
michael@0 86 uint64_t *ireg_end = ireg_args + 8;
michael@0 87 double *freg_args = (double *)ireg_end;
michael@0 88 double *freg_end = freg_args + 8;
michael@0 89 uint64_t *stack_args = (uint64_t *)freg_end;
michael@0 90
michael@0 91 // leave room for 'that' argument in x0
michael@0 92 ++ireg_args;
michael@0 93
michael@0 94 for (uint32_t i = 0; i < paramCount; i++, s++) {
michael@0 95 if (s->IsPtrData()) {
michael@0 96 alloc_word(ireg_args, stack_args, ireg_end, (uint64_t)s->ptr);
michael@0 97 continue;
michael@0 98 }
michael@0 99 // According to the ABI, integral types that are smaller than 8 bytes
michael@0 100 // are to be passed in 8-byte registers or 8-byte stack slots.
michael@0 101 switch (s->type) {
michael@0 102 case nsXPTType::T_FLOAT:
michael@0 103 alloc_float(freg_args, stack_args, freg_end, s->val.f);
michael@0 104 break;
michael@0 105 case nsXPTType::T_DOUBLE:
michael@0 106 alloc_double(freg_args, stack_args, freg_end, s->val.d);
michael@0 107 break;
michael@0 108 case nsXPTType::T_I8: alloc_word(ireg_args, stk, end, s->val.i8); break;
michael@0 109 case nsXPTType::T_I16: alloc_word(ireg_args, stk, end, s->val.i16); break;
michael@0 110 case nsXPTType::T_I32: alloc_word(ireg_args, stk, end, s->val.i32); break;
michael@0 111 case nsXPTType::T_I64: alloc_word(ireg_args, stk, end, s->val.i64); break;
michael@0 112 case nsXPTType::T_U8: alloc_word(ireg_args, stk, end, s->val.u8); break;
michael@0 113 case nsXPTType::T_U16: alloc_word(ireg_args, stk, end, s->val.u16); break;
michael@0 114 case nsXPTType::T_U32: alloc_word(ireg_args, stk, end, s->val.u32); break;
michael@0 115 case nsXPTType::T_U64: alloc_word(ireg_args, stk, end, s->val.u64); break;
michael@0 116 case nsXPTType::T_BOOL: alloc_word(ireg_args, stk, end, s->val.b); break;
michael@0 117 case nsXPTType::T_CHAR: alloc_word(ireg_args, stk, end, s->val.c); break;
michael@0 118 case nsXPTType::T_WCHAR: alloc_word(ireg_args, stk, end, s->val.wc); break;
michael@0 119 default:
michael@0 120 // all the others are plain pointer types
michael@0 121 alloc_word(ireg_args, stack_args, ireg_end,
michael@0 122 reinterpret_cast<uint64_t>(s->val.p));
michael@0 123 break;
michael@0 124 }
michael@0 125 }
michael@0 126 }
michael@0 127
michael@0 128 extern "C" nsresult _NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
michael@0 129 uint32_t paramCount, nsXPTCVariant* params);
michael@0 130
michael@0 131 EXPORT_XPCOM_API(nsresult)
michael@0 132 NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
michael@0 133 uint32_t paramCount, nsXPTCVariant* params)
michael@0 134 {
michael@0 135 return _NS_InvokeByIndex(that, methodIndex, paramCount, params);
michael@0 136 }

mercurial