source:
pkg/vinnie/main/iceweasel/trunk/debian/patches/porting/Add-xptcall-support-for-SH4-processors.patch
@
7516
| Revision 7516, 16.7 KB checked in by alanbach-guest, 2 years ago (diff) |
|---|
-
xpcom/reflect/xptcall/src/md/unix/Makefile.in
From: Mike Hommey <glandium@debian.org> Date: Fri, 30 Apr 2010 11:03:50 +0200 Subject: Add xptcall support for SH4 processors Closes: #553593 https://bugzilla.mozilla.org/show_bug.cgi?id=382214 --- xpcom/reflect/xptcall/src/md/unix/Makefile.in | 11 + .../xptcall/src/md/unix/xptcinvoke_linux_sh.cpp | 203 +++++++++++++++ .../xptcall/src/md/unix/xptcstubs_linux_sh.cpp | 271 ++++++++++++++++++++ 3 files changed, 485 insertions(+), 0 deletions(-) create mode 100644 xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_sh.cpp create mode 100644 xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_sh.cpp diff --git a/xpcom/reflect/xptcall/src/md/unix/Makefile.in b/xpcom/reflect/xptcall/src/md/unix/Makefile.in index 56be8b2..46d1797 100644
a b CPPSRCS := xptcinvoke_linux_s390x.cpp xptcstubs_linux_s390x.cpp 448 448 CXXFLAGS += -fno-strict-aliasing -fno-inline -fomit-frame-pointer -mbackchain 449 449 endif 450 450 451 ############ 452 # SuperH 453 ############ 454 # 455 # 456 # Currently, tested on sh4 and sh4a (non sh4al and sh4al-dsp..) 457 ifeq ($(OS_ARCH),Linux) 458 ifneq (,$(filter sh4 sh4a,$(OS_TEST))) 459 CPPSRCS := xptcinvoke_linux_sh.cpp xptcstubs_linux_sh.cpp 460 endif 461 endif 451 462 452 463 # we don't want the shared lib, but we want to force the creation of a static lib. 453 464 FORCE_STATIC_LIB = 1 -
new file xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_sh.cpp
diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_sh.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_linux_sh.cpp new file mode 100644 index 0000000..ca4807d
- + 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * 3 * ***** BEGIN LICENSE BLOCK ***** 4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 5 * 6 * The contents of this file are subject to the Mozilla Public License Version 7 * 1.1 (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * http://www.mozilla.org/MPL/ 10 * 11 * Software distributed under the License is distributed on an "AS IS" basis, 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 * for the specific language governing rights and limitations under the 14 * License. 15 * 16 * The Original Code is mozilla.org code. 17 * 18 * The Initial Developer of the Original Code is 19 * Netscape Communications Corporation. 20 * Portions created by the Initial Developer are Copyright (C) 1998 21 * the Initial Developer. All Rights Reserved. 22 * 23 * Contributor(s): 24 * - Copyright (C) 2008-2009 STMicroelectronics 25 * 26 * Alternatively, the contents of this file may be used under the terms of 27 * either of the GNU General Public License Version 2 or later (the "GPL"), 28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 29 * in which case the provisions of the GPL or the LGPL are applicable instead 30 * of those above. If you wish to allow use of your version of this file only 31 * under the terms of either the GPL or the LGPL, and not to allow others to 32 * use your version of this file under the terms of the MPL, indicate your 33 * decision by deleting the provisions above and replace them with the notice 34 * and other provisions required by the GPL or the LGPL. If you do not delete 35 * the provisions above, a recipient may use your version of this file under 36 * the terms of any one of the MPL, the GPL or the LGPL. 37 * 38 * Based on the neutroni port, however that assumed that the compiler was pushing params 39 * onto the stack. Change to take this into account. 40 * 41 * ***** END LICENSE BLOCK ***** */ 42 43 #include "xptcprivate.h" 44 45 extern "C" { 46 47 const int c_int_register_params = 4; 48 const int c_float_register_params = 8; 49 50 static PRUint32 __attribute__((__used__)) 51 copy_to_stack(PRUint32 **that,PRUint32 methodIndex,PRUint32 paramCount, nsXPTCVariant* s,PRUint32* data) 52 { 53 int intCount = 1; // Because of that 54 int floatCount = 0; 55 PRUint32 *intRegParams=data+1 ; 56 float *floatRegParams = (float *)(data+4); 57 58 /* Push the that register into the right place so it can be restored on exit */ 59 *data= (PRUint32)(that); 60 data+=12; /* 4 integer registers, and 8 floating point registers */ 61 62 for ( PRUint32 i = 0; i < paramCount; ++i, ++s ) 63 { 64 nsXPTType type = s->IsPtrData() ? nsXPTType::T_I32 : s->type; 65 66 switch ( type ) { 67 case nsXPTType::T_I64: 68 case nsXPTType::T_U64: 69 // Space to pass in registers? 70 if ( (c_int_register_params - intCount) >= 2 ) { 71 *((PRInt64 *) intRegParams) = s->val.i64; 72 intRegParams += 2; 73 intCount += 2; 74 } 75 else { 76 *((PRInt64*) data) = s->val.i64; 77 data += 2; 78 } 79 break; 80 case nsXPTType::T_FLOAT: 81 // Space to pass in registers? 82 if ( floatCount < c_float_register_params ) { 83 *floatRegParams = s->val.f; 84 ++floatCount; 85 ++floatRegParams; 86 } 87 else { 88 *((float*) data) = s->val.f; 89 ++data; 90 } 91 break; 92 case nsXPTType::T_DOUBLE: 93 // Space to pass in registers? 94 if ( (c_float_register_params - floatCount) >= 2 ) { 95 if ( (floatCount & 1) != 0 ) { 96 ++floatCount; 97 ++floatRegParams; 98 } 99 *(double *)floatRegParams = s->val.d; 100 floatCount += 2; 101 floatRegParams += 2; 102 } 103 else { 104 *((double *) data) = s->val.d; 105 data += 2; 106 } 107 break; 108 default: // 32 (non-float) value 109 PRInt32 value = (PRInt32) (s->IsPtrData() ? s->ptr : s->val.p); 110 // Space to pass in registers? 111 if ( intCount < c_int_register_params ) { 112 *intRegParams = value; 113 ++intRegParams; 114 ++intCount; 115 } 116 else { 117 *data = value; 118 ++data; 119 } 120 break; 121 } 122 } 123 124 /* Now calculate the return address 125 * Dereference that to get vtable pointer 126 */ 127 return *( (*(that))+(methodIndex) ); 128 129 } 130 131 } 132 133 /* This was originally done as a C function, but the original code was 134 * relying on how the compiler laid out the stack. Later versions of 135 * gcc do a better job of optimising and never push the parameters on the 136 * stack. So it is simpler to just write the whole thing in assembler anyway 137 */ 138 139 /* Because the SH processor passes the first few parameters in registers 140 it is a bit tricky setting things up right. To make things easier, 141 all the hard work will be done by copy_to_stack above. We pass to it 142 a chunk of memory, the bottom of which will be copied to registers r4 to r7 143 and fr4 to fr11 before calling the target function. 144 */ 145 146 /* r4= that, r5=methodIndex,r6=paramCount,r7=params */ 147 148 __asm__ ( 149 150 151 /* Make space for parameters to be passed to the method. Assume worst case 152 8 bytes per parameter. Also leave space for 4 longs and 8 floats that 153 will be put into registers. The worst case is all int64 parameters 154 and even in this case 8 bytes are passed in registers so we can 155 deduct this from our allocation. 156 */ 157 ".section .text\n" 158 ".balign 4\n" 159 ".global NS_InvokeByIndex_P\n" 160 "NS_InvokeByIndex_P:\n" 161 "mov.l r14, @-r15 \n\t" // Push frame 162 "sts.l pr, @-r15 \n\t" // Push link 163 "mov.l r8, @-r15 \n\t" // Save 164 "mov r15, r14\n\t" // Set frame 165 "mov #3, r1 \n\t" // Assume worse case, all params are 64bit, hence *8 166 "mov r6, r2\n\t" 167 "shld r1, r2 \n\t" 168 "mov r2, r8 \n\t" // Save stack drop 169 "add #48, r2 \n\t" // Space for 4 longs, 8 floats 170 "sub r2, r15 \n\t" // Drop stack 171 "mov.l 1f, r1 \n\t" // Get address of copy_to_stack_function 172 "jsr @r1 \n\t" 173 "mov.l r15, @-r15 \n\t" // Params will be dumped here 174 "add #4, r15 \n\t" // Pop stack ptr param. r0 contains method address 175 176 /* Now everything is laid out nicely in the stack. We just have to 177 load values at the top end of the memory area into registers and 178 make the call. We may load more things into registers than needed, 179 but nobody will care about that. 180 */ 181 182 "mov.l @r15+, r4 \n\t" // that 183 "mov.l @r15+, r5 \n\t" 184 "mov.l @r15+, r6 \n\t" 185 "mov.l @r15+, r7 \n\t" 186 "fmov.s @r15+, fr5 \n\t" 187 "fmov.s @r15+, fr4 \n\t" 188 "fmov.s @r15+, fr7 \n\t" 189 "fmov.s @r15+, fr6 \n\t" 190 "fmov.s @r15+, fr9 \n\t" 191 "fmov.s @r15+, fr8 \n\t" 192 "fmov.s @r15+, fr11 \n\t" 193 "jsr @r0 \n\t" // Invoke method 194 "fmov.s @r15+, fr10 \n\t" 195 "add r8, r15\n\t" // Pop stack back 196 "mov.l @r15+, r8\n\t" // Restore r8 197 "lds.l @r15+, pr\n\t" 198 "rts\n\t" 199 "mov.l @r15+, r14\n\t" 200 ".balign 4\n\t" 201 "1: .long copy_to_stack \n\t" 202 ); 203 -
new file xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_sh.cpp
diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_sh.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_linux_sh.cpp new file mode 100644 index 0000000..cf9fcea
- + 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* ***** BEGIN LICENSE BLOCK ***** 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 * 5 * The contents of this file are subject to the Mozilla Public License Version 6 * 1.1 (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * http://www.mozilla.org/MPL/ 9 * 10 * Software distributed under the License is distributed on an "AS IS" basis, 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 * for the specific language governing rights and limitations under the 13 * License. 14 * 15 * The Original Code is mozilla.org code. 16 * 17 * The Initial Developer of the Original Code is 18 * Netscape Communications Corporation. 19 * Portions created by the Initial Developer are Copyright (C) 1999 20 * the Initial Developer. All Rights Reserved. 21 * 22 * Contributor(s): 23 * - Copyright (C) 2008-2009 STMicroelectronics 24 * 25 * Alternatively, the contents of this file may be used under the terms of 26 * either of the GNU General Public License Version 2 or later (the "GPL"), 27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 * in which case the provisions of the GPL or the LGPL are applicable instead 29 * of those above. If you wish to allow use of your version of this file only 30 * under the terms of either the GPL or the LGPL, and not to allow others to 31 * use your version of this file under the terms of the MPL, indicate your 32 * decision by deleting the provisions above and replace them with the notice 33 * and other provisions required by the GPL or the LGPL. If you do not delete 34 * the provisions above, a recipient may use your version of this file under 35 * the terms of any one of the MPL, the GPL or the LGPL. 36 * 37 * Based on the neutrino code, with some bug fixes and using the C preprocessor 38 * like all the other ports rather than the python script. 39 * 40 * ***** END LICENSE BLOCK ***** */ 41 42 #include "xptcprivate.h" 43 #include "xptiprivate.h" 44 45 const int c_int_register_params = 3; 46 const int c_float_register_params = 8; 47 48 /* 49 Dispatch function for all stubs. 50 51 The parameters to the original function are spread between 'data' which 52 is value of the stack pointer when the stub was called, intRegParams which 53 points to an area containing the values of r5, r6 and r7 when the stub was 54 called and floatRegParams which points to an area containing the values 55 of float registers fr4 to fr11 when the stub was called. 56 57 */ 58 extern "C" nsresult 59 PrepareAndDispatch(nsXPTCStubBase* self, int methodIndex, PRUint32* data, 60 PRUint32 *intRegParams, float *floatRegParams) 61 { 62 #define PARAM_BUFFER_COUNT 16 63 64 nsresult result = NS_ERROR_FAILURE; 65 int intCount = 0; 66 int floatCount = 0; 67 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; 68 nsXPTCMiniVariant* dispatchParams = NULL; 69 const nsXPTMethodInfo* info; 70 PRUint8 paramCount; 71 PRUint8 i; 72 73 NS_ASSERTION(self,"no self"); 74 75 self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info); 76 NS_ASSERTION(info,"no interface info"); 77 78 paramCount = info->GetParamCount(); 79 80 // setup variant array pointer 81 if(paramCount > PARAM_BUFFER_COUNT) 82 dispatchParams = new nsXPTCMiniVariant[paramCount]; 83 else 84 dispatchParams = paramBuffer; 85 NS_ASSERTION(dispatchParams,"no place for params"); 86 87 for ( i = 0; i < paramCount; ++i ) { 88 const nsXPTParamInfo& param = info->GetParam(i); 89 nsXPTCMiniVariant* dp = &dispatchParams[i]; 90 nsXPTType type = param.IsOut() ? nsXPTType::T_I32 : param.GetType(); 91 92 switch ( type ) { 93 case nsXPTType::T_I64: 94 case nsXPTType::T_U64: 95 // Was this passed in a register? 96 if ( (c_int_register_params - intCount) >= 2 ) { 97 dp->val.i64 = *((PRInt64 *) intRegParams); 98 intRegParams += 2; 99 intCount += 2; 100 } 101 else { 102 dp->val.i64 = *((PRInt64*) data); 103 data += 2; 104 } 105 break; 106 case nsXPTType::T_FLOAT: 107 // Was this passed in a register? 108 if ( floatCount < c_float_register_params ) { 109 dp->val.f = *floatRegParams; 110 ++floatCount; 111 ++floatRegParams; 112 } 113 else { 114 dp->val.f = *((float*) data); 115 ++data; 116 } 117 break; 118 case nsXPTType::T_DOUBLE: 119 // Was this passed in a register? 120 if ( (c_float_register_params - floatCount) >= 2 ) { 121 if ( floatCount & 1 != 0 ) { 122 ++floatCount; 123 ++floatRegParams; 124 } 125 dp->val.d = *(double *)floatRegParams; 126 floatCount += 2; 127 floatRegParams += 2; 128 } 129 else { 130 dp->val.d = *((double *) data); 131 data += 2; 132 } 133 break; 134 default: // 32-bit (non-float) value 135 // Was this passed in a register? 136 if ( intCount < c_int_register_params ) { 137 dp->val.i32 = *intRegParams; 138 ++intRegParams; 139 ++intCount; 140 } 141 else { 142 dp->val.i32 = *data; 143 ++data; 144 } 145 break; 146 } 147 } 148 149 result = self->mOuter->CallMethod((PRUint16)methodIndex, info, dispatchParams); 150 151 if(dispatchParams != paramBuffer) 152 delete [] dispatchParams; 153 154 return result; 155 } 156 157 158 __asm__ ( 159 ".text\n" 160 ".little\n" 161 ".section .rodata\n" 162 163 ".globl SharedStub\n" 164 ".type SharedStub, @function\n" 165 "SharedStub:\n" 166 "mov r15, r1\n" 167 "mov.l r14,@-r15\n" 168 "sts.l pr,@-r15\n" 169 "mov r15, r14\n" 170 171 /* Some parameters might have been passed in registers, so push them 172 * all onto the stack, PrepareAndDispatch can then work out whats what 173 * given method type information. 174 */ 175 "mov.l r7, @-r15\n" 176 "mov.l r6, @-r15\n" 177 "mov.l r5, @-r15\n" 178 "mov r15, r7\n" /* r7 = PrepareAndDispatch intRegParams param */ 179 180 "fmov.s fr10, @-r15\n" 181 "fmov.s fr11, @-r15\n" 182 "fmov.s fr8, @-r15\n" 183 "fmov.s fr9, @-r15\n" 184 "fmov.s fr6, @-r15\n" 185 "fmov.s fr7, @-r15\n" 186 "fmov.s fr4, @-r15\n" 187 "fmov.s fr5, @-r15\n" 188 "mov.l r15, @-r15\n" /* PrepareAndDispatch floatRegParams param */ 189 190 "mov r1, r6\n" /* r6 = PrepareAndDispatch data param */ 191 192 "mov.l 1f, r1\n" 193 "jsr @r1\n" /* Note, following instruction is executed first*/ 194 "mov r2, r5\n" /* r5 = PrepareAndDispatch methodIndex param */ 195 196 "mov r14,r15\n" 197 "lds.l @r15+,pr\n" 198 "mov.l @r15+,r14\n" 199 "rts\n" 200 "nop\n" 201 ".align 2\n" 202 "1:\n" 203 ".long PrepareAndDispatch\n" 204 ); 205 206 #define STUB_ENTRY(n) \ 207 __asm__( \ 208 ".text\n" \ 209 ".align 1 \n" \ 210 ".if " #n " < 10\n\t" \ 211 ".globl _ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \ 212 ".type _ZN14nsXPTCStubBase5Stub" #n "Ev,@function\n"\ 213 "_ZN14nsXPTCStubBase5Stub" #n "Ev:\n\t" \ 214 ".elseif " #n " < 100\n\t" \ 215 ".globl _ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \ 216 ".type _ZN14nsXPTCStubBase6Stub" #n "Ev,@function\n"\ 217 "_ZN14nsXPTCStubBase6Stub" #n "Ev:\n\t" \ 218 ".elseif " #n " < 1000\n\t" \ 219 ".globl _ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \ 220 ".type _ZN14nsXPTCStubBase7Stub" #n "Ev,@function\n"\ 221 "_ZN14nsXPTCStubBase7Stub" #n "Ev:\n\t" \ 222 ".else\n\t" \ 223 ".err \"stub number " #n " >= 1000 not yet supported\"\n\t" \ 224 ".endif\n\t" \ 225 "mov.l 1f, r1 \n" \ 226 ".if "#n" < 128 \n" \ 227 "jmp @r1 \n" \ 228 " mov #"#n",r2 \n" \ 229 ".elseif "#n" < 256 \n" \ 230 "mov #"#n", r2 \n" \ 231 "jmp @r1 \n" \ 232 " extu.b r2, r2 \n" \ 233 ".else \n" \ 234 "mov #"#n" & 0xff,r2 \n" \ 235 "extu.b r2, r2 \n" \ 236 "mov #"#n">>8, r3 \n" \ 237 "shll8 r3 \n" \ 238 "jmp @r1 \n" \ 239 " or r3, r2 \n" \ 240 ".endif \n" \ 241 ".if "#n" % 20 == 0\n" \ 242 ".align 2\n" \ 243 "1:\n" \ 244 ".long SharedStub\n" \ 245 ".endif\n" \ 246 ); 247 248 249 /* Due to the fact that the SH4 can only load forward labels, we have 250 * to use sentinel_entry to output the last label. A better solution 251 * would be to introduce a STUB_LAST macro in the defs.in file, but 252 * this will do for now 253 */ 254 255 #define SENTINEL_ENTRY(n) \ 256 __asm__( \ 257 ".if "#n" == 0 \n" \ 258 ".text \n" \ 259 ".align 2\n" \ 260 "1:\n" \ 261 ".long SharedStub\n" \ 262 ".endif\n" \ 263 ); \ 264 \ 265 nsresult nsXPTCStubBase::Sentinel##n() \ 266 { \ 267 NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ 268 return NS_ERROR_NOT_IMPLEMENTED; \ 269 } 270 271 #include "xptcstubsdef.inc"
Note: See TracBrowser
for help on using the repository browser.


