diff options
Diffstat (limited to 'SCM/continue-ia64.S')
-rw-r--r-- | SCM/continue-ia64.S | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/SCM/continue-ia64.S b/SCM/continue-ia64.S new file mode 100644 index 0000000..ba61e38 --- /dev/null +++ b/SCM/continue-ia64.S @@ -0,0 +1,339 @@ +/* "continue-ia64.S" continuation support for ia64. + * Copyright (C) 2006 Free Software Foundation, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ + +/* Author: Richard E. Harke */ + +/* +struct Continuation {jump_buf jmpbuf; + long thrwval; + long length; + STACKITEM *stkbse; +#ifdef __ia64__ + long *bspbse; + long bsplength; + long rnat; +#endif + CONTINUATION_OTHER other; + struct Continuation *parent; + }; +*/ +/* Define offsets for elements of a Continuation structure */ +#include "contoffset-ia64.S" + + + .global must_malloc + .text + .align 32 + .global make_root_continuation + .proc make_root_continuation +make_root_continuation: + .prologue + .save ar.pfs,r33 + alloc r33 = ar.pfs,1,3,2,0 + .save rp,r34 + mov r34 = b0 + .body + addl r14 = @ltoffx(s_call_cc), r1 + mov out0 = cont_size + mov loc2 = gp + ;; + ld8.mov r14 = [r14], s_call_cc + ;; + adds out1 = 18, r14 + ;; + br.call.sptk.many b0=must_malloc + ;; + mov gp = r35 + cmp.eq p6,p0 = r8,r0 + adds r14 = stkbse_off,r8 + adds r15 = bspbse_off,r8 + (p6) br.cond.dpnt mrcexit + ;; + flushrs + st8 [r14] = r12 + ;; + mov r31 = ar.bsp + ;; + adds r14 = length_off,r8 + st8 [r15] = r31 + adds r16 = bsplength_off,r8 + ;; + st8 [r14] = r0 + st8 [r16] = r0 + adds r15 = parent_off,r8 + ;; + st8 [r15] = r8 +mrcexit: + mov ar.pfs = r33 + mov b0 = r34 + ;; + br.ret.sptk.many b0 + .endp make_root_continuation + + /* + register usage + r32 - r39 used in modulo loop (requires multiple of 8) + r40 save r32 from input + r41 save return - b0 + r42 ar.pfs + r43 save gp (r1) + r44 ar.bsp + r45 out0 + r46 out1 + */ + .global make_continuation + .proc make_continuation +make_continuation: + .prologue + .save ar.pfs, r42 + alloc r42 = ar.pfs, 1,12, 2, 8 + mov r43 = r1 + .save rp, r41 + mov r41 = b0 + mov r40 = r32 + ;; + .body + adds r14 = bspbse_off,r40 + adds r17 = stkbse_off,r40 + ;; + mov r44 = ar.bsp + ld8 r15 = [r14] // bspbse from parent + ld8 r18 = [r17] // stkbse from parent + ;; + sub r16 = r44,r15 // length of bsp to save + sub r19 = r18,r12 // length of stack to save + addl r15 = @ltoffx(s_call_cc), r1 + ;; + add r45 = r16,r19 // bsp len plus stack len + ld8.mov r14 = [r15], s_call_cc + ;; + adds r14 = 18, r14 + adds r45 = cont_size, r45 // add in length of continuation struct + ;; + mov r46 = r14 + br.call.sptk.many b0 = must_malloc + mov r1 = r43 + cmp.eq p6, p7 = 0, r8 + (p6) br.cond.dptk .L5 + ;; +.L1: + flushrs + adds r14 = bspbse_off,r40 + adds r17 = stkbse_off,r40 + ;; + mov r31 = ar.rsc + ld8 r15 = [r14] // bsp in parent + ld8 r18 = [r17] // stack base in parent + ;; + and r30 = ~0x3,r31 + sub r16 = r44,r15 // length of bsp to save + sub r19 = r18,r12 // length of stack to save + ;; + mov ar.rsc = r30 // set enforced idle + shr r16 = r16,3 // number of longs not bytes + adds r21 = length_off,r8 + adds r22 = bsplength_off,r8 + shr r19 = r19,3 // number of longs not bytes + ;; + mov r30 = ar.rnat + add r20 = r16,r19 // total length to save + st8 [r22] = r16 // store the bsp length + adds r14 = bspbse_off,r8 + adds r17 = stkbse_off,r8 + ;; + st8 [r14] = r44 // save current bsp + st8 [r17] = r18 // stkbse same as parent stkbse + adds r22 = parent_off,r8 + st8 [r21] = r20 // store the length + ;; + adds r21 = rnat_off,r8 + st8 [r22] = r40 // store parent continuation + mov r29 = ar.lc // need to preserve ar.lc + mov r28 = pr // need to preserve pr.rot + adds r16 = -1,r16 + ;; + st8 [r21] = r30 // store rnat's + mov ar.lc = r16 + mov ar.ec = 3 + mov pr.rot = 0x10000 + adds r27 = cont_size,r8 + adds r19 = -1,r19 + ;; +.L6: + (p16) ld8 r32 = [r15],8 + (p18) st8 [r27] = r34,8 + br.ctop.sptk.few .L6 + ;; + mov r26 = r12 + clrrrb + ;; + mov ar.ec = 3 + mov pr.rot = 0x10000 + mov ar.lc = r19 + ;; +.L7: + (p16) ld8 r32 = [r26],8 + (p18) st8 [r27] = r34,8 + br.ctop.sptk.few .L7 + ;; + mov ar.lc = r29 // restore ar.lc + mov pr = r28,0x1003e // restore pr + mov ar.rsc = r31 // restore ar.rsc + ;; +.L5: + mov ar.pfs = r42 + mov b0 = r41 + br.ret.sptk.many b0 + .endp make_continuation + + + .global thrown_value + .global longjmp + .global dynthrow + .proc dynthrow +dynthrow: + .prologue + .save ar.pfs, r42 + alloc r42 = ar.pfs, 1,12, 2, 8 + mov r43 = r1 + .save rp, r44 + mov r44 = b0 + ld8 r40 = [r32],8 + mov r31 = ar.rsc + movl r2 = ~0x3fff0003 + ;; +.L3: + flushrs + adds r14 = bspbse_off,r40 + adds r17 = stkbse_off,r40 + and r30 = r2,r31 + ;; + ld8 r41 = [r32] + ld8 r15 = [r14] // bsp + ld8 r18 = [r17] // stack base + mov ar.rsc = r30 // set enforced idle + ;; +.L2: + loadrs + adds r21 = length_off,r40 + adds r22 = bsplength_off,r40 + ;; + mov ar.bspstore = r15 + ld8 r16 = [r21] // get total length (number of longs) + ld8 r17 = [r22] // get bsp length (number of longs) + ;; + sub r20 = r16,r17 // compute stack length + shl r25 = r17,3 + ;; + mov r29 = ar.lc // need to preserve ar.lc + mov r28 = pr // need to preserve pr.rot + sub r15 = r15,r25 // adjust bsp beginning + shl r14 = r20,3 + adds r17 = -1,r17 + adds r21 = rnat_off,r40 + ;; + sub r18 = r18,r14 // adjust stack to lowest + mov ar.lc = r17 + mov ar.ec = 3 + mov pr.rot = 0x10000 + adds r27 = cont_size,r40 + adds r20 = -1,r20 + ;; +.L8: + (p16) ld8 r32 = [r27],8 + (p18) st8 [r15] = r34,8 + br.ctop.sptk.few .L8 + ;; + ld8 r14 = [r21] // get the rnat's + clrrrb + ;; + mov ar.ec = 3 + mov pr.rot = 0x10000 + mov ar.lc = r20 + ;; +.L9: + (p16) ld8 r32 = [r27],8 + (p18) st8 [r18] = r34,8 + br.ctop.sptk.few .L9 + ;; + mov ar.rnat = r14 + mov ar.lc = r29 // restore ar.lc + mov pr = r28,0x1003e // restore pr + addl r26 = @gprel(thrown_value),gp + ;; + mov ar.rsc = r31 // restore ar.rsc + st8 [r26] = r41 + mov r45 = r40 + mov r46 = 1 + ;; + br.call.sptk.many b0 = longjmp +// the following should not be executed + mov r1 = r43 + mov ar.pfs = r42 + mov b0 = r44 + br.ret.sptk.many b0 + .endp dynthrow + + .global mark_locations + .global mark_regs_ia64 + .proc mark_regs_ia64 +mark_regs_ia64: + .prologue + .save ar.pfs, r35 + alloc r35 = ar.pfs, 1, 4, 2, 0 + .save rp, r33 + mov r33 = b0 + mov r36 = r1 + mov r34 = r12 + adds r17 = stkbse_off, r32 + ;; + adds r12 = -32, r12 + ld8 r19 = [r17] + ;; + adds r18 = 16,r12 + ;; + sub r38 = r19, r18 + ;; + st8 [r18] = r4, 8 + shr r38 = r38, 3 + ;; + st8 [r18] = r5, 8 + ;; + st8 [r18] = r6, 8 + ;; + st8 [r18] = r7 + mov r37 = r12 + br.call.sptk.many b0 = mark_locations + flushrs + mov r1 = r36 + adds r17 = bspbse_off, r32 + ;; + mov r20 = ar.bsp + ;; + ld8 r37 = [r17] + ;; + sub r38 = r20, r37 + ;; + shr r38 = r38, 3 + br.call.sptk.many b0 = mark_locations + mov r1 = r36 + mov r12 = r34 + mov ar.pfs = r35 + mov b0 = r33 + br.ret.sptk.many b0 + .endp mark_regs_ia64 |