1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "xptcprivate.h"
7
8 #ifndef __AARCH64EL__
9 #error "Only little endian compatibility was tested"
10 #endif
11
12 /*
13 * This is for AArch64 ABI
14 *
15 * When we're called, the "gp" registers are stored in gprData and
16 * the "fp" registers are stored in fprData. Each array has 8 regs
17 * but first reg in gprData is a placeholder for 'self'.
18 */
19 extern "C" nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase * self,uint32_t methodIndex,uint64_t * args,uint64_t * gprData,double * fprData)20 PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args,
21 uint64_t *gprData, double *fprData)
22 {
23 #define PARAM_BUFFER_COUNT 16
24 #define PARAM_GPR_COUNT 8
25 #define PARAM_FPR_COUNT 8
26
27 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
28 nsXPTCMiniVariant* dispatchParams = NULL;
29 const nsXPTMethodInfo* info;
30
31 NS_ASSERTION(self,"no self");
32
33 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
34 NS_ASSERTION(info,"no method info");
35
36 uint32_t paramCount = info->GetParamCount();
37
38 // setup variant array pointer
39 if (paramCount > PARAM_BUFFER_COUNT) {
40 dispatchParams = new nsXPTCMiniVariant[paramCount];
41 } else {
42 dispatchParams = paramBuffer;
43 }
44 NS_ASSERTION(dispatchParams,"no place for params");
45
46 const uint8_t indexOfJSContext = info->IndexOfJSContext();
47
48 uint64_t* ap = args;
49 uint32_t next_gpr = 1; // skip first arg which is 'self'
50 uint32_t next_fpr = 0;
51 for (uint32_t i = 0; i < paramCount; i++) {
52 const nsXPTParamInfo& param = info->GetParam(i);
53 const nsXPTType& type = param.GetType();
54 nsXPTCMiniVariant* dp = &dispatchParams[i];
55
56 if (i == indexOfJSContext) {
57 if (next_gpr < PARAM_GPR_COUNT)
58 next_gpr++;
59 else
60 ap++;
61 }
62
63 if (param.IsOut() || !type.IsArithmetic()) {
64 if (next_gpr < PARAM_GPR_COUNT) {
65 dp->val.p = (void*)gprData[next_gpr++];
66 } else {
67 dp->val.p = (void*)*ap++;
68 }
69 continue;
70 }
71
72 switch (type) {
73 case nsXPTType::T_I8:
74 if (next_gpr < PARAM_GPR_COUNT) {
75 dp->val.i8 = (int8_t)gprData[next_gpr++];
76 } else {
77 dp->val.i8 = (int8_t)*ap++;
78 }
79 break;
80
81 case nsXPTType::T_I16:
82 if (next_gpr < PARAM_GPR_COUNT) {
83 dp->val.i16 = (int16_t)gprData[next_gpr++];
84 } else {
85 dp->val.i16 = (int16_t)*ap++;
86 }
87 break;
88
89 case nsXPTType::T_I32:
90 if (next_gpr < PARAM_GPR_COUNT) {
91 dp->val.i32 = (int32_t)gprData[next_gpr++];
92 } else {
93 dp->val.i32 = (int32_t)*ap++;
94 }
95 break;
96
97 case nsXPTType::T_I64:
98 if (next_gpr < PARAM_GPR_COUNT) {
99 dp->val.i64 = (int64_t)gprData[next_gpr++];
100 } else {
101 dp->val.i64 = (int64_t)*ap++;
102 }
103 break;
104
105 case nsXPTType::T_U8:
106 if (next_gpr < PARAM_GPR_COUNT) {
107 dp->val.u8 = (uint8_t)gprData[next_gpr++];
108 } else {
109 dp->val.u8 = (uint8_t)*ap++;
110 }
111 break;
112
113 case nsXPTType::T_U16:
114 if (next_gpr < PARAM_GPR_COUNT) {
115 dp->val.u16 = (uint16_t)gprData[next_gpr++];
116 } else {
117 dp->val.u16 = (uint16_t)*ap++;
118 }
119 break;
120
121 case nsXPTType::T_U32:
122 if (next_gpr < PARAM_GPR_COUNT) {
123 dp->val.u32 = (uint32_t)gprData[next_gpr++];
124 } else {
125 dp->val.u32 = (uint32_t)*ap++;
126 }
127 break;
128
129 case nsXPTType::T_U64:
130 if (next_gpr < PARAM_GPR_COUNT) {
131 dp->val.u64 = (uint64_t)gprData[next_gpr++];
132 } else {
133 dp->val.u64 = (uint64_t)*ap++;
134 }
135 break;
136
137 case nsXPTType::T_FLOAT:
138 if (next_fpr < PARAM_FPR_COUNT) {
139 memcpy(&dp->val.f, &fprData[next_fpr++], sizeof(dp->val.f));
140 } else {
141 memcpy(&dp->val.f, ap++, sizeof(dp->val.f));
142 }
143 break;
144
145 case nsXPTType::T_DOUBLE:
146 if (next_fpr < PARAM_FPR_COUNT) {
147 memcpy(&dp->val.d, &fprData[next_fpr++], sizeof(dp->val.d));
148 } else {
149 memcpy(&dp->val.d, ap++, sizeof(dp->val.d));
150 }
151 break;
152
153 case nsXPTType::T_BOOL:
154 if (next_gpr < PARAM_GPR_COUNT) {
155 dp->val.b = (bool)(uint8_t)gprData[next_gpr++];
156 } else {
157 dp->val.b = (bool)(uint8_t)*ap++;
158 }
159 break;
160
161 case nsXPTType::T_CHAR:
162 if (next_gpr < PARAM_GPR_COUNT) {
163 dp->val.c = (char)gprData[next_gpr++];
164 } else {
165 dp->val.c = (char)*ap++;
166 }
167 break;
168
169 case nsXPTType::T_WCHAR:
170 if (next_gpr < PARAM_GPR_COUNT) {
171 dp->val.wc = (wchar_t)gprData[next_gpr++];
172 } else {
173 dp->val.wc = (wchar_t)*ap++;
174 }
175 break;
176
177 default:
178 NS_ASSERTION(0, "bad type");
179 break;
180 }
181 }
182
183 nsresult result = self->mOuter->CallMethod((uint16_t)methodIndex, info,
184 dispatchParams);
185
186 if (dispatchParams != paramBuffer) {
187 delete [] dispatchParams;
188 }
189
190 return result;
191 }
192
193 // Load w17 with the constant 'n' and branch to SharedStub().
194 # define STUB_ENTRY(n) \
195 __asm__ ( \
196 ".section \".text\" \n\t" \
197 ".align 2\n\t" \
198 ".if "#n" < 10 \n\t" \
199 ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \
200 ".hidden _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \
201 ".type _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n" \
202 "_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t" \
203 ".elseif "#n" < 100 \n\t" \
204 ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \
205 ".hidden _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \
206 ".type _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n" \
207 "_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t" \
208 ".elseif "#n" < 1000 \n\t" \
209 ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \
210 ".hidden _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \
211 ".type _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n" \
212 "_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t" \
213 ".else \n\t" \
214 ".err \"stub number "#n" >= 1000 not yet supported\"\n" \
215 ".endif \n\t" \
216 "mov w17,#"#n" \n\t" \
217 "b SharedStub \n" \
218 );
219
220 #define SENTINEL_ENTRY(n) \
221 nsresult nsXPTCStubBase::Sentinel##n() \
222 { \
223 NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
224 return NS_ERROR_NOT_IMPLEMENTED; \
225 }
226
227 #include "xptcstubsdef.inc"
228