// Select C numeric constant .radix C .psr abi64 .psr lsb // Section has executable code .section .text, "ax","progbits" // procedure named 'SharedStub' .proc SharedStub // manual bundling .explicit .global PrepareAndDispatch // .exclass PrepareAndDispatch, @fullyvisible .type PrepareAndDispatch,@function SharedStub:: // 10 arguments, first 8 are the input arguments of previous // function call. The 9th one is methodIndex and the 10th is the // pointer to the remaining input arguments. The last two arguments // are passed in memory. .prologue .save ar.pfs , r41 // allocate 8 input args, 4 local args, and 5 output args alloc r41 = ar.pfs, 8, 4, 5, 0 // M .save rp, r40 mov r40 = rp // I add out4 = 24, sp ;; // I .save ar.unat, r42 mov r42 = ar.unat // M .fframe 144 add sp = -144, sp // A // unwind table already knows gp, don't need to specify anything add r43 = 0, gp ;; // A // We have possible 8 integer registers and 8 float registers that could // be arguments. We also have a stack region from the previous // stack frame that may hold some stack arguments. // We need to write the integer registers to a memory region, write // the float registers to a memory region (making sure we don't step // on NAT while touching the registers). We also mark the memory // address of the stack arguments. // We then call PrepareAndDispatch() specifying the three memory // region pointers. .body add out0 = 0, in0 // A move self ptr // 144 bytes = 16 byte stack header + 64 byte int space + 64 byte float space // methodIndex is at 144 + 16 bytes away from current sp // (current frame + previous frame header) ld8 out4 = [out4] // M restarg address add r11 = 160, sp ;; // A address of methodIndex ld8 out1 = [r11] // M load methodIndex // sp + 16 is the start of intargs add out2 = 16, sp // A address of intargs // the intargs take up 64 bytes, so sp + 16 + 64 is the start of floatargs add out3 = 80, sp ;; // A address of floatargs add r11 = 0, out2 ;; // A st8.spill [r11] = in1, 8 // M add r10 = 0, out3 ;; // A st8.spill [r11] = in2, 8 ;; // M st8.spill [r11] = in3, 8 // M nop.i 0 ;; // I st8.spill [r11] = in4, 8 ;; // M st8.spill [r11] = in5, 8 // M nop.i 0 ;; // I st8.spill [r11] = in6, 8 ;; // M st8.spill [r11] = in7 // M fclass.nm p14,p15 = f8,@nat ;; // F (p14) stfd [r10] = f8, 8 // M (p15) add r10 = 8, r10 // A fclass.nm p12,p13 = f9,@nat ;; // F (p12) stfd [r10] = f9, 8 // M (p13) add r10 = 8, r10 // A fclass.nm p14,p15 =f10,@nat ;; // F (p14) stfd [r10] = f10, 8 // M (p15) add r10 = 8, r10 // A fclass.nm p12,p13 =f11,@nat ;; // F (p12) stfd [r10] = f11, 8 // M (p13) add r10 = 8, r10 // A fclass.nm p14,p15 =f12,@nat ;; // F (p14) stfd [r10] = f12, 8 // M (p15) add r10 = 8, r10 // A fclass.nm p12,p13 =f13,@nat ;; // F (p12) stfd [r10] = f13, 8 // M (p13) add r10 = 8, r10 // A fclass.nm p14,p15 =f14,@nat ;; // F (p14) stfd [r10] = f14, 8 // M (p15) add r10 = 8, r10 // A fclass.nm p12,p13 =f15,@nat ;; // F (p12) stfd [r10] = f15, 8 // M (p13) add r10 = 8, r10 // A // branch to PrepareAndDispatch br.call.dptk.few rp = PrepareAndDispatch ;; // B // epilog mov ar.unat = r42 // M mov ar.pfs = r41 // I mov rp = r40 ;; // I add gp = 0, r43 // A add sp = 144, sp // A br.ret.dptk.few rp ;; // B .endp /* Magic indicating no need for an executable stack */ .section .note.GNU-stack, "", @progbits