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