xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ipf64.s	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,146 @@
     1.4 +
     1.5 +// Select C numeric constant
     1.6 +        .radix  C
     1.7 +// for 64 bit mode, use .psr abi64
     1.8 +        .psr    abi64
     1.9 +// little endian
    1.10 +        .psr    lsb
    1.11 +// Section has executable code
    1.12 +        .section .text, "ax","progbits"
    1.13 +// procedure named 'NS_InvokeByIndex'
    1.14 +        .proc   NS_InvokeByIndex
    1.15 +// manual bundling
    1.16 +        .explicit
    1.17 +
    1.18 +// extern "C" uint32_t
    1.19 +// invoke_copy_to_stack(uint64_t* d,
    1.20 +//   const uint32_t paramCount, nsXPTCVariant* s)
    1.21 +        .global invoke_copy_to_stack
    1.22 +//      .exclass  invoke_copy_to_stack, @fullyvisible
    1.23 +        .type   invoke_copy_to_stack,@function
    1.24 +
    1.25 +//      .exclass  NS_InvokeByIndex, @fullyvisible
    1.26 +        .type   NS_InvokeByIndex,@function
    1.27 +
    1.28 +// XPTC_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
    1.29 +//   uint32_t paramCount, nsXPTCVariant* params);
    1.30 +NS_InvokeByIndex::
    1.31 +        .prologue
    1.32 +        .save ar.pfs, r37
    1.33 +// allocate 4 input args, 6 local args, and 8 output args
    1.34 +        alloc           r37 = ar.pfs, 4, 6, 8, 0   // M
    1.35 +        nop.i           0                       ;; // I
    1.36 +
    1.37 +// unwind table already knows gp, no need to specify anything
    1.38 +        add             r39 = 0, gp                // A
    1.39 +        .save rp, r36
    1.40 +        mov             r36 = rp                   // I
    1.41 +        .vframe r38
    1.42 +        add             r38 = 0, sp             ;; // A
    1.43 +
    1.44 +// We first calculate the amount of extra memory stack space required
    1.45 +// for the arguments, and register storage.
    1.46 +// We then call invoke_copy_to_stack() to write the argument contents
    1.47 +// to the specified memory regions.
    1.48 +// We then copy the integer arguments to integer registers, and floating
    1.49 +// arguments to float registers.
    1.50 +// Lastly we load the virtual table jump pointer, and call the target
    1.51 +// subroutine.
    1.52 +
    1.53 +// in0 : that
    1.54 +// in1 : methodIndex
    1.55 +// in2 : paramCount
    1.56 +// in3 : params
    1.57 +
    1.58 +// stack frame size is 16 + (8 * even(paramCount)) + 64 + 64
    1.59 +// 16 byte frame header
    1.60 +// 8 * even(paramCount) memory argument area
    1.61 +// 64 bytes integer register area
    1.62 +// 64 bytes float register area
    1.63 +// This scheme makes sure stack fram size is a multiple of 16
    1.64 +
    1.65 +        .body
    1.66 +        add             r10 = 8, r0          // A
    1.67 +// r41 points to float register area
    1.68 +        add             r41 = -64, sp        // A
    1.69 +// r40 points to int register area
    1.70 +        add             r40 = -128, sp    ;; // A
    1.71 +
    1.72 +        add             out1 = 0, r40        // A
    1.73 +        add             out2 = 0, r41        // A
    1.74 +        tbit.z          p14,p15 = in2,0   ;; // I
    1.75 +
    1.76 +// compute 8 * even(paramCount)
    1.77 +(p14)   shladd          r11 = in2, 3, r0  ;; // A
    1.78 +(p15)   shladd          r11 = in2, 3, r10 ;; // A
    1.79 +        sub             out0 = r40, r11   ;; // A
    1.80 +
    1.81 +// advance the stack frame
    1.82 +        add             sp = -16, out0       // A
    1.83 +        add             out3 = 0, in2        // A
    1.84 +        add             out4 = 0, in3        // A
    1.85 +
    1.86 +// branch to invoke_copy_to_stack
    1.87 +        br.call.sptk.few rp = invoke_copy_to_stack ;; // B
    1.88 +
    1.89 +// restore gp
    1.90 +        add             gp = 0, r39          // A
    1.91 +        add             out0 = 0, in0        // A
    1.92 +
    1.93 +// load the integer and float registers
    1.94 +        ld8             out1 = [r40], 8      // M
    1.95 +        ldfd            f8 = [r41], 8       ;; // M
    1.96 +
    1.97 +        ld8             out2 = [r40], 8      // M
    1.98 +        ldfd            f9 = [r41], 8       ;; // M
    1.99 +
   1.100 +        ld8             out3 = [r40], 8      // M
   1.101 +        ldfd            f10 = [r41], 8      ;; // M
   1.102 +
   1.103 +        ld8             out4 = [r40], 8      // M
   1.104 +        ldfd            f11 = [r41], 8      ;; // M
   1.105 +
   1.106 +        ld8             out5 = [r40], 8      // M
   1.107 +        ldfd            f12 = [r41], 8      ;; // M
   1.108 +// 16 * methodIndex
   1.109 +        shladd          r11 = in1, 4, r0     // A
   1.110 +
   1.111 +        ld8             out6 = [r40], 8      // M
   1.112 +        ldfd            f13 = [r41], 8      ;; // M
   1.113 +
   1.114 +        ld8             out7 = [r40], 8      // M
   1.115 +        ldfd            f14 = [r41], 8       // M
   1.116 +        add             r8 = 0, in0       ;; // A
   1.117 +
   1.118 +// look up virtual base table and dispatch to target subroutine
   1.119 +// This section assumes 64 bit pointer mode, and virtual base table
   1.120 +// layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html
   1.121 +
   1.122 +// load base table
   1.123 +        ld8             r8 = [r8]         ;; // M
   1.124 +        add             r8 = r11, r8      ;; // A
   1.125 +
   1.126 + // first entry is jump pointer, second entry is gp
   1.127 +        add             r9 = 8, r8       ;; // A
   1.128 +// load jump pointer
   1.129 +        ld8             r8 = [r8]
   1.130 +
   1.131 +// load gp
   1.132 +        ld8             gp = [r9]        ;; // M
   1.133 +        mov             b6 = r8          ;; // I
   1.134 +
   1.135 +// branch to target virtual function
   1.136 +        br.call.sptk.few rp = b6          ;; // B
   1.137 +
   1.138 +// epilog
   1.139 +        mov             ar.pfs = r37         // I
   1.140 +        mov             rp = r36          ;; // I
   1.141 +
   1.142 +        add             sp = 0, r38          // A
   1.143 +        add             gp = 0, r39          // A
   1.144 +        br.ret.sptk.few rp                ;; // B
   1.145 +
   1.146 +        .endp
   1.147 +
   1.148 +/* Magic indicating no need for an executable stack */
   1.149 +.section .note.GNU-stack, "", @progbits ; .previous

mercurial