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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1
michael@0 2 // Select C numeric constant
michael@0 3 .radix C
michael@0 4 // for 64 bit mode, use .psr abi64
michael@0 5 .psr abi64
michael@0 6 // little endian
michael@0 7 .psr lsb
michael@0 8 // Section has executable code
michael@0 9 .section .text, "ax","progbits"
michael@0 10 // procedure named 'NS_InvokeByIndex'
michael@0 11 .proc NS_InvokeByIndex
michael@0 12 // manual bundling
michael@0 13 .explicit
michael@0 14
michael@0 15 // extern "C" uint32_t
michael@0 16 // invoke_copy_to_stack(uint64_t* d,
michael@0 17 // const uint32_t paramCount, nsXPTCVariant* s)
michael@0 18 .global invoke_copy_to_stack
michael@0 19 // .exclass invoke_copy_to_stack, @fullyvisible
michael@0 20 .type invoke_copy_to_stack,@function
michael@0 21
michael@0 22 // .exclass NS_InvokeByIndex, @fullyvisible
michael@0 23 .type NS_InvokeByIndex,@function
michael@0 24
michael@0 25 // XPTC_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
michael@0 26 // uint32_t paramCount, nsXPTCVariant* params);
michael@0 27 NS_InvokeByIndex::
michael@0 28 .prologue
michael@0 29 .save ar.pfs, r37
michael@0 30 // allocate 4 input args, 6 local args, and 8 output args
michael@0 31 alloc r37 = ar.pfs, 4, 6, 8, 0 // M
michael@0 32 nop.i 0 ;; // I
michael@0 33
michael@0 34 // unwind table already knows gp, no need to specify anything
michael@0 35 add r39 = 0, gp // A
michael@0 36 .save rp, r36
michael@0 37 mov r36 = rp // I
michael@0 38 .vframe r38
michael@0 39 add r38 = 0, sp ;; // A
michael@0 40
michael@0 41 // We first calculate the amount of extra memory stack space required
michael@0 42 // for the arguments, and register storage.
michael@0 43 // We then call invoke_copy_to_stack() to write the argument contents
michael@0 44 // to the specified memory regions.
michael@0 45 // We then copy the integer arguments to integer registers, and floating
michael@0 46 // arguments to float registers.
michael@0 47 // Lastly we load the virtual table jump pointer, and call the target
michael@0 48 // subroutine.
michael@0 49
michael@0 50 // in0 : that
michael@0 51 // in1 : methodIndex
michael@0 52 // in2 : paramCount
michael@0 53 // in3 : params
michael@0 54
michael@0 55 // stack frame size is 16 + (8 * even(paramCount)) + 64 + 64
michael@0 56 // 16 byte frame header
michael@0 57 // 8 * even(paramCount) memory argument area
michael@0 58 // 64 bytes integer register area
michael@0 59 // 64 bytes float register area
michael@0 60 // This scheme makes sure stack fram size is a multiple of 16
michael@0 61
michael@0 62 .body
michael@0 63 add r10 = 8, r0 // A
michael@0 64 // r41 points to float register area
michael@0 65 add r41 = -64, sp // A
michael@0 66 // r40 points to int register area
michael@0 67 add r40 = -128, sp ;; // A
michael@0 68
michael@0 69 add out1 = 0, r40 // A
michael@0 70 add out2 = 0, r41 // A
michael@0 71 tbit.z p14,p15 = in2,0 ;; // I
michael@0 72
michael@0 73 // compute 8 * even(paramCount)
michael@0 74 (p14) shladd r11 = in2, 3, r0 ;; // A
michael@0 75 (p15) shladd r11 = in2, 3, r10 ;; // A
michael@0 76 sub out0 = r40, r11 ;; // A
michael@0 77
michael@0 78 // advance the stack frame
michael@0 79 add sp = -16, out0 // A
michael@0 80 add out3 = 0, in2 // A
michael@0 81 add out4 = 0, in3 // A
michael@0 82
michael@0 83 // branch to invoke_copy_to_stack
michael@0 84 br.call.sptk.few rp = invoke_copy_to_stack ;; // B
michael@0 85
michael@0 86 // restore gp
michael@0 87 add gp = 0, r39 // A
michael@0 88 add out0 = 0, in0 // A
michael@0 89
michael@0 90 // load the integer and float registers
michael@0 91 ld8 out1 = [r40], 8 // M
michael@0 92 ldfd f8 = [r41], 8 ;; // M
michael@0 93
michael@0 94 ld8 out2 = [r40], 8 // M
michael@0 95 ldfd f9 = [r41], 8 ;; // M
michael@0 96
michael@0 97 ld8 out3 = [r40], 8 // M
michael@0 98 ldfd f10 = [r41], 8 ;; // M
michael@0 99
michael@0 100 ld8 out4 = [r40], 8 // M
michael@0 101 ldfd f11 = [r41], 8 ;; // M
michael@0 102
michael@0 103 ld8 out5 = [r40], 8 // M
michael@0 104 ldfd f12 = [r41], 8 ;; // M
michael@0 105 // 16 * methodIndex
michael@0 106 shladd r11 = in1, 4, r0 // A
michael@0 107
michael@0 108 ld8 out6 = [r40], 8 // M
michael@0 109 ldfd f13 = [r41], 8 ;; // M
michael@0 110
michael@0 111 ld8 out7 = [r40], 8 // M
michael@0 112 ldfd f14 = [r41], 8 // M
michael@0 113 add r8 = 0, in0 ;; // A
michael@0 114
michael@0 115 // look up virtual base table and dispatch to target subroutine
michael@0 116 // This section assumes 64 bit pointer mode, and virtual base table
michael@0 117 // layout from the ABI http://www.codesourcery.com/cxx-abi/abi.html
michael@0 118
michael@0 119 // load base table
michael@0 120 ld8 r8 = [r8] ;; // M
michael@0 121 add r8 = r11, r8 ;; // A
michael@0 122
michael@0 123 // first entry is jump pointer, second entry is gp
michael@0 124 add r9 = 8, r8 ;; // A
michael@0 125 // load jump pointer
michael@0 126 ld8 r8 = [r8]
michael@0 127
michael@0 128 // load gp
michael@0 129 ld8 gp = [r9] ;; // M
michael@0 130 mov b6 = r8 ;; // I
michael@0 131
michael@0 132 // branch to target virtual function
michael@0 133 br.call.sptk.few rp = b6 ;; // B
michael@0 134
michael@0 135 // epilog
michael@0 136 mov ar.pfs = r37 // I
michael@0 137 mov rp = r36 ;; // I
michael@0 138
michael@0 139 add sp = 0, r38 // A
michael@0 140 add gp = 0, r39 // A
michael@0 141 br.ret.sptk.few rp ;; // B
michael@0 142
michael@0 143 .endp
michael@0 144
michael@0 145 /* Magic indicating no need for an executable stack */
michael@0 146 .section .note.GNU-stack, "", @progbits ; .previous

mercurial