1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_alpha_openbsd.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,144 @@ 1.4 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* Platform specific code to invoke XPCOM methods on native objects */ 1.10 + 1.11 +#include "xptcprivate.h" 1.12 + 1.13 +/* Prototype specifies unmangled function name and disables unused warning */ 1.14 +static void 1.15 +invoke_copy_to_stack(uint64_t* d, uint32_t paramCount, nsXPTCVariant* s) 1.16 +__asm__("invoke_copy_to_stack") __attribute__((used)); 1.17 + 1.18 +static void 1.19 +invoke_copy_to_stack(uint64_t* d, uint32_t paramCount, nsXPTCVariant* s) 1.20 +{ 1.21 + const uint8_t NUM_ARG_REGS = 6-1; // -1 for "this" pointer 1.22 + 1.23 + for(uint32_t i = 0; i < paramCount; i++, d++, s++) 1.24 + { 1.25 + if(s->IsPtrData()) 1.26 + { 1.27 + *d = (uint64_t)s->ptr; 1.28 + continue; 1.29 + } 1.30 + switch(s->type) 1.31 + { 1.32 + case nsXPTType::T_I8 : *d = (uint64_t)s->val.i8; break; 1.33 + case nsXPTType::T_I16 : *d = (uint64_t)s->val.i16; break; 1.34 + case nsXPTType::T_I32 : *d = (uint64_t)s->val.i32; break; 1.35 + case nsXPTType::T_I64 : *d = (uint64_t)s->val.i64; break; 1.36 + case nsXPTType::T_U8 : *d = (uint64_t)s->val.u8; break; 1.37 + case nsXPTType::T_U16 : *d = (uint64_t)s->val.u16; break; 1.38 + case nsXPTType::T_U32 : *d = (uint64_t)s->val.u32; break; 1.39 + case nsXPTType::T_U64 : *d = (uint64_t)s->val.u64; break; 1.40 + case nsXPTType::T_FLOAT : 1.41 + if(i < NUM_ARG_REGS) 1.42 + { 1.43 + // convert floats to doubles if they are to be passed 1.44 + // via registers so we can just deal with doubles later 1.45 + union { uint64_t u64; double d; } t; 1.46 + t.d = (double)s->val.f; 1.47 + *d = t.u64; 1.48 + } 1.49 + else 1.50 + // otherwise copy to stack normally 1.51 + *d = (uint64_t)s->val.u32; 1.52 + break; 1.53 + case nsXPTType::T_DOUBLE : *d = (uint64_t)s->val.u64; break; 1.54 + case nsXPTType::T_BOOL : *d = (uint64_t)s->val.b; break; 1.55 + case nsXPTType::T_CHAR : *d = (uint64_t)s->val.c; break; 1.56 + case nsXPTType::T_WCHAR : *d = (uint64_t)s->val.wc; break; 1.57 + default: 1.58 + // all the others are plain pointer types 1.59 + *d = (uint64_t)s->val.p; 1.60 + break; 1.61 + } 1.62 + } 1.63 +} 1.64 + 1.65 +/* 1.66 + * EXPORT_XPCOM_API(nsresult) 1.67 + * NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, 1.68 + * uint32_t paramCount, nsXPTCVariant* params) 1.69 + */ 1.70 +__asm__( 1.71 + "#### NS_InvokeByIndex ####\n" 1.72 +".text\n\t" 1.73 + ".align 5\n\t" 1.74 + ".globl NS_InvokeByIndex\n\t" 1.75 + ".ent NS_InvokeByIndex\n" 1.76 +"NS_InvokeByIndex:\n\t" 1.77 + ".frame $15,32,$26,0\n\t" 1.78 + ".mask 0x4008000,-32\n\t" 1.79 + "ldgp $29,0($27)\n" 1.80 +"$NS_InvokeByIndex..ng:\n\t" 1.81 + "subq $30,32,$30\n\t" 1.82 + "stq $26,0($30)\n\t" 1.83 + "stq $15,8($30)\n\t" 1.84 + "bis $30,$30,$15\n\t" 1.85 + ".prologue 1\n\t" 1.86 + 1.87 + /* 1.88 + * Allocate enough stack space to hold the greater of 6 or "paramCount"+1 1.89 + * parameters. (+1 for "this" pointer) Room for at least 6 parameters 1.90 + * is required for storage of those passed via registers. 1.91 + */ 1.92 + 1.93 + "bis $31,5,$2\n\t" /* count = MAX(5, "paramCount") */ 1.94 + "cmplt $2,$18,$1\n\t" 1.95 + "cmovne $1,$18,$2\n\t" 1.96 + "s8addq $2,16,$1\n\t" /* room for count+1 params (8 bytes each) */ 1.97 + "bic $1,15,$1\n\t" /* stack space is rounded up to 0 % 16 */ 1.98 + "subq $30,$1,$30\n\t" 1.99 + 1.100 + "stq $16,0($30)\n\t" /* save "that" (as "this" pointer) */ 1.101 + "stq $17,16($15)\n\t" /* save "methodIndex" */ 1.102 + 1.103 + "addq $30,8,$16\n\t" /* pass stack pointer */ 1.104 + "bis $18,$18,$17\n\t" /* pass "paramCount" */ 1.105 + "bis $19,$19,$18\n\t" /* pass "params" */ 1.106 + "bsr $26,$invoke_copy_to_stack..ng\n\t" /* call invoke_copy_to_stack */ 1.107 + 1.108 + /* 1.109 + * Copy the first 6 parameters to registers and remove from stack frame. 1.110 + * Both the integer and floating point registers are set for each parameter 1.111 + * except the first which is the "this" pointer. (integer only) 1.112 + * The floating point registers are all set as doubles since the 1.113 + * invoke_copy_to_stack function should have converted the floats. 1.114 + */ 1.115 + "ldq $16,0($30)\n\t" /* integer registers */ 1.116 + "ldq $17,8($30)\n\t" 1.117 + "ldq $18,16($30)\n\t" 1.118 + "ldq $19,24($30)\n\t" 1.119 + "ldq $20,32($30)\n\t" 1.120 + "ldq $21,40($30)\n\t" 1.121 + "ldt $f17,8($30)\n\t" /* floating point registers */ 1.122 + "ldt $f18,16($30)\n\t" 1.123 + "ldt $f19,24($30)\n\t" 1.124 + "ldt $f20,32($30)\n\t" 1.125 + "ldt $f21,40($30)\n\t" 1.126 + 1.127 + "addq $30,48,$30\n\t" /* remove params from stack */ 1.128 + 1.129 + /* 1.130 + * Call the virtual function with the constructed stack frame. 1.131 + */ 1.132 + "bis $16,$16,$1\n\t" /* load "this" */ 1.133 + "ldq $2,16($15)\n\t" /* load "methodIndex" */ 1.134 + "ldq $1,0($1)\n\t" /* load vtable */ 1.135 + "s8addq $2,$31,$2\n\t" /* vtable index = "methodIndex" * 8 */ 1.136 + "addq $1,$2,$1\n\t" 1.137 + "ldq $27,0($1)\n\t" /* load address of function */ 1.138 + "jsr $26,($27),0\n\t" /* call virtual function */ 1.139 + "ldgp $29,0($26)\n\t" 1.140 + 1.141 + "bis $15,$15,$30\n\t" 1.142 + "ldq $26,0($30)\n\t" 1.143 + "ldq $15,8($30)\n\t" 1.144 + "addq $30,32,$30\n\t" 1.145 + "ret $31,($26),1\n\t" 1.146 + ".end NS_InvokeByIndex" 1.147 + );