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)
  • Added new iceweasel to Vinnie
  • 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 
    448448CXXFLAGS        += -fno-strict-aliasing -fno-inline -fomit-frame-pointer -mbackchain 
    449449endif 
    450450 
     451############ 
     452# SuperH 
     453############ 
     454# 
     455# 
     456# Currently, tested on sh4 and sh4a (non sh4al and sh4al-dsp..) 
     457ifeq ($(OS_ARCH),Linux) 
     458ifneq (,$(filter sh4 sh4a,$(OS_TEST))) 
     459CPPSRCS         := xptcinvoke_linux_sh.cpp xptcstubs_linux_sh.cpp 
     460endif 
     461endif 
    451462 
    452463# we don't want the shared lib, but we want to force the creation of a static lib. 
    453464FORCE_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 
     45extern "C" { 
     46 
     47const int c_int_register_params = 4; 
     48const int c_float_register_params = 8; 
     49 
     50static PRUint32 __attribute__((__used__)) 
     51copy_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 
     45const int c_int_register_params = 3; 
     46const 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 */ 
     58extern "C" nsresult 
     59PrepareAndDispatch(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                                        \ 
     265nsresult 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.