Home | History | Annotate | Line # | Download | only in rs6000
      1   1.1  mrg /*  This file contains the exception-handling save_world and
      2   1.1  mrg  *  restore_world routines, which need to do a run-time check to see if
      3   1.1  mrg  *  they should save and restore the vector registers.
      4   1.1  mrg  *
      5  1.10  mrg  *   Copyright (C) 2004-2022 Free Software Foundation, Inc.
      6   1.1  mrg  *
      7   1.1  mrg  * This file is free software; you can redistribute it and/or modify it
      8   1.1  mrg  * under the terms of the GNU General Public License as published by the
      9   1.1  mrg  * Free Software Foundation; either version 3, or (at your option) any
     10   1.1  mrg  * later version.
     11   1.1  mrg  *
     12   1.1  mrg  * This file is distributed in the hope that it will be useful, but
     13   1.1  mrg  * WITHOUT ANY WARRANTY; without even the implied warranty of
     14   1.1  mrg  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15   1.1  mrg  * General Public License for more details.
     16   1.1  mrg  *
     17   1.1  mrg  * Under Section 7 of GPL version 3, you are granted additional
     18   1.1  mrg  * permissions described in the GCC Runtime Library Exception, version
     19   1.1  mrg  * 3.1, as published by the Free Software Foundation.
     20   1.1  mrg  *
     21   1.1  mrg  * You should have received a copy of the GNU General Public License and
     22   1.1  mrg  * a copy of the GCC Runtime Library Exception along with this program;
     23   1.1  mrg  * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24   1.1  mrg  * <http://www.gnu.org/licenses/>.
     25   1.1  mrg  */
     26   1.1  mrg 
     27   1.1  mrg #ifndef __ppc64__
     28   1.1  mrg 
     29   1.1  mrg 	.machine ppc7400
     30   1.1  mrg .data
     31   1.1  mrg 	.align 2
     32   1.1  mrg 
     33   1.1  mrg #ifdef __DYNAMIC__
     34   1.1  mrg 
     35   1.1  mrg .non_lazy_symbol_pointer
     36   1.1  mrg L_has_vec$non_lazy_ptr:
     37   1.1  mrg 	.indirect_symbol __cpu_has_altivec
     38   1.1  mrg 	.long	0
     39   1.1  mrg #else
     40   1.1  mrg 
     41   1.1  mrg /* For static, "pretend" we have a non-lazy-pointer.  */
     42   1.1  mrg 
     43   1.1  mrg L_has_vec$non_lazy_ptr:
     44   1.1  mrg 	.long __cpu_has_altivec
     45   1.1  mrg 
     46   1.1  mrg #endif
     47   1.1  mrg 
     48   1.1  mrg 
     49   1.1  mrg .text
     50   1.1  mrg 	.align 2
     51   1.1  mrg 
     52   1.1  mrg /* save_world and rest_world save/restore F14-F31 and possibly V20-V31
     53   1.1  mrg    (assuming you have a CPU with vector registers; we use a global var
     54   1.1  mrg    provided by the System Framework to determine this.)
     55   1.1  mrg 
     56   1.1  mrg    SAVE_WORLD takes R0 (the caller`s caller`s return address) and R11
     57   1.1  mrg    (the stack frame size) as parameters.  It returns the updated VRsave
     58   1.1  mrg    in R0 if we`re on a CPU with vector regs.
     59   1.1  mrg 
     60   1.1  mrg    For gcc3 onward, we need to save and restore CR as well, since scheduled
     61   1.1  mrg    prologs can cause comparisons to be moved before calls to save_world.
     62   1.1  mrg 
     63   1.1  mrg    USES: R0 R11 R12  */
     64   1.1  mrg 
     65   1.1  mrg .private_extern save_world
     66   1.1  mrg save_world:
     67   1.1  mrg 	stw r0,8(r1)
     68   1.1  mrg 	mflr r0
     69   1.1  mrg 	bcl 20,31,Ls$pb
     70   1.1  mrg Ls$pb:	mflr r12
     71   1.1  mrg 	addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Ls$pb)
     72   1.1  mrg 	lwz r12,lo16(L_has_vec$non_lazy_ptr-Ls$pb)(r12)
     73   1.1  mrg 	mtlr r0
     74   1.1  mrg 	lwz r12,0(r12)
     75   1.1  mrg 				/* grab CR  */
     76   1.1  mrg 	mfcr r0
     77   1.1  mrg 				/* test HAS_VEC  */
     78   1.1  mrg 	cmpwi r12,0
     79   1.1  mrg 	stfd f14,-144(r1)
     80   1.1  mrg 	stfd f15,-136(r1)
     81   1.1  mrg 	stfd f16,-128(r1)
     82   1.1  mrg 	stfd f17,-120(r1)
     83   1.1  mrg 	stfd f18,-112(r1)
     84   1.1  mrg 	stfd f19,-104(r1)
     85   1.1  mrg 	stfd f20,-96(r1)
     86   1.1  mrg 	stfd f21,-88(r1)
     87   1.1  mrg 	stfd f22,-80(r1)
     88   1.1  mrg 	stfd f23,-72(r1)
     89   1.1  mrg 	stfd f24,-64(r1)
     90   1.1  mrg 	stfd f25,-56(r1)
     91   1.1  mrg 	stfd f26,-48(r1)
     92   1.1  mrg 	stfd f27,-40(r1)
     93   1.1  mrg 	stfd f28,-32(r1)
     94   1.1  mrg 	stfd f29,-24(r1)
     95   1.1  mrg 	stfd f30,-16(r1)
     96   1.1  mrg 	stfd f31,-8(r1)
     97   1.1  mrg 	stmw r13,-220(r1)
     98   1.1  mrg 				/* stash CR  */
     99   1.1  mrg 	stw r0,4(r1)
    100   1.1  mrg 				/* set R12 pointing at Vector Reg save area  */
    101   1.1  mrg 	addi r12,r1,-224
    102   1.1  mrg 				/* allocate stack frame  */
    103   1.1  mrg 	stwux r1,r1,r11
    104   1.1  mrg 				/* ...but return if HAS_VEC is zero   */
    105   1.1  mrg 	bne+ L$saveVMX
    106   1.1  mrg 				/* Not forgetting to restore CR.  */
    107   1.1  mrg 	mtcr r0
    108   1.1  mrg 	blr
    109   1.1  mrg 
    110   1.1  mrg L$saveVMX:
    111   1.1  mrg 				/* We're saving Vector regs too.  */
    112   1.1  mrg 				/* Restore CR from R0.  No More Branches!  */
    113   1.1  mrg 	mtcr r0
    114   1.1  mrg 
    115   1.1  mrg 	/* We should really use VRSAVE to figure out which vector regs
    116   1.1  mrg 	   we actually need to save and restore.  Some other time :-/  */
    117   1.1  mrg 
    118   1.1  mrg 	li r11,-192
    119   1.1  mrg 	stvx v20,r11,r12
    120   1.1  mrg 	li r11,-176
    121   1.1  mrg 	stvx v21,r11,r12
    122   1.1  mrg 	li r11,-160
    123   1.1  mrg 	stvx v22,r11,r12
    124   1.1  mrg 	li r11,-144
    125   1.1  mrg 	stvx v23,r11,r12
    126   1.1  mrg 	li r11,-128
    127   1.1  mrg 	stvx v24,r11,r12
    128   1.1  mrg 	li r11,-112
    129   1.1  mrg 	stvx v25,r11,r12
    130   1.1  mrg 	li r11,-96
    131   1.1  mrg 	stvx v26,r11,r12
    132   1.1  mrg 	li r11,-80
    133   1.1  mrg 	stvx v27,r11,r12
    134   1.1  mrg 	li r11,-64
    135   1.1  mrg 	stvx v28,r11,r12
    136   1.1  mrg 	li r11,-48
    137   1.1  mrg 	stvx v29,r11,r12
    138   1.1  mrg 	li r11,-32
    139   1.1  mrg 	stvx v30,r11,r12
    140   1.1  mrg 	mfspr r0,VRsave
    141   1.1  mrg 	li r11,-16
    142   1.1  mrg 	stvx v31,r11,r12
    143   1.1  mrg 	stw r0,0(r12)		/* VRsave lives at -224(R1).  */
    144   1.1  mrg 	ori r0,r0,0xfff		/* We just saved these.  */
    145   1.1  mrg 	mtspr VRsave,r0
    146   1.1  mrg 	blr
    147   1.1  mrg 
    148   1.1  mrg /* rest_world  is jumped to, not called, so no need to worry about LR.
    149   1.1  mrg    clobbers R0, R7, R11 and R12.  This just undoes the work done above.  */
    150   1.1  mrg 
    151   1.1  mrg 	.private_extern rest_world
    152   1.1  mrg rest_world:
    153   1.1  mrg 
    154   1.1  mrg 	lwz r11, 0(r1)		/* Pickup previous SP  */
    155   1.1  mrg 	li r7, 0		/* Stack offset is zero, r10 is ignored.  */
    156   1.1  mrg 	b Lrest_world_eh_r7
    157   1.1  mrg 
    158   1.1  mrg /* eh_rest_world_r10 is jumped to, not called, so no need to worry about LR.
    159   1.1  mrg    R10 is the C++ EH stack adjust parameter, we return to the caller`s caller.
    160   1.1  mrg 
    161   1.1  mrg    clobbers: R0, R7, R11 and R12
    162   1.1  mrg    uses    : R10
    163   1.1  mrg    RETURNS : C++ EH Data registers (R3 - R6).  */
    164   1.1  mrg 
    165   1.1  mrg 	.private_extern eh_rest_world_r10
    166   1.1  mrg eh_rest_world_r10:
    167   1.1  mrg 
    168   1.1  mrg 	lwz r11, 0(r1)		/* Pickup previous SP  */
    169   1.1  mrg 	mr  r7,r10		/* Stack offset.  */
    170   1.1  mrg 
    171   1.1  mrg 	/* pickup the C++ EH data regs (R3 - R6.)  */
    172   1.1  mrg 	lwz r6,-420(r11)
    173   1.1  mrg 	lwz r5,-424(r11)
    174   1.1  mrg 	lwz r4,-428(r11)
    175   1.1  mrg 	lwz r3,-432(r11)
    176   1.1  mrg 
    177   1.1  mrg 	/* Fall through to Lrest_world_eh_r7.  */
    178   1.1  mrg 
    179   1.1  mrg /* When we are doing the exception-handling epilog, R7 contains the offset to
    180   1.1  mrg    add to the SP.
    181   1.1  mrg 
    182   1.1  mrg    clobbers: R0, R11 and R12
    183   1.1  mrg    uses    : R7.  */
    184   1.1  mrg 
    185   1.1  mrg Lrest_world_eh_r7:
    186   1.1  mrg 	/* See if we have Altivec.  */
    187   1.1  mrg 	bcl 20,31,Lr7$pb
    188   1.1  mrg Lr7$pb: mflr r12
    189   1.1  mrg 
    190   1.1  mrg 	addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Lr7$pb)
    191   1.1  mrg 	lwz r12,lo16(L_has_vec$non_lazy_ptr-Lr7$pb)(r12)
    192   1.1  mrg 	lwz r12,0(r12)		/* R12 := HAS_VEC  */
    193   1.1  mrg 	cmpwi r12,0
    194   1.1  mrg 	lmw r13,-220(r11)
    195   1.1  mrg 	beq L.rest_world_fp_eh
    196   1.1  mrg 
    197   1.1  mrg 	/* We have Altivec, restore VRsave and V20..V31  */
    198   1.1  mrg 	lwz r0,-224(r11)
    199   1.1  mrg 	li r12,-416
    200   1.1  mrg 	mtspr VRsave,r0
    201   1.1  mrg 	lvx v20,r11,r12
    202   1.1  mrg 	li r12,-400
    203   1.1  mrg 	lvx v21,r11,r12
    204   1.1  mrg 	li r12,-384
    205   1.1  mrg 	lvx v22,r11,r12
    206   1.1  mrg 	li r12,-368
    207   1.1  mrg 	lvx v23,r11,r12
    208   1.1  mrg 	li r12,-352
    209   1.1  mrg 	lvx v24,r11,r12
    210   1.1  mrg 	li r12,-336
    211   1.1  mrg 	lvx v25,r11,r12
    212   1.1  mrg 	li r12,-320
    213   1.1  mrg 	lvx v26,r11,r12
    214   1.1  mrg 	li r12,-304
    215   1.1  mrg 	lvx v27,r11,r12
    216   1.1  mrg 	li r12,-288
    217   1.1  mrg 	lvx v28,r11,r12
    218   1.1  mrg 	li r12,-272
    219   1.1  mrg 	lvx v29,r11,r12
    220   1.1  mrg 	li r12,-256
    221   1.1  mrg 	lvx v30,r11,r12
    222   1.1  mrg 	li r12,-240
    223   1.1  mrg 	lvx v31,r11,r12
    224   1.1  mrg 
    225   1.1  mrg L.rest_world_fp_eh:
    226   1.1  mrg 	lwz r0,4(r11)		/* recover saved CR  */
    227   1.1  mrg 	lfd f14,-144(r11)
    228   1.1  mrg 	lfd f15,-136(r11)
    229   1.1  mrg 	lfd f16,-128(r11)
    230   1.1  mrg 	lfd f17,-120(r11)
    231   1.1  mrg 	lfd f18,-112(r11)
    232   1.1  mrg 	lfd f19,-104(r11)
    233   1.1  mrg 	lfd f20,-96(r11)
    234   1.1  mrg 	lfd f21,-88(r11)
    235   1.1  mrg 	lfd f22,-80(r11)
    236   1.1  mrg 	lfd f23,-72(r11)
    237   1.1  mrg 	lfd f24,-64(r11)
    238   1.1  mrg 	lfd f25,-56(r11)
    239   1.1  mrg 	lfd f26,-48(r11)
    240   1.1  mrg 	lfd f27,-40(r11)
    241   1.1  mrg 	lfd f28,-32(r11)
    242   1.1  mrg 	lfd f29,-24(r11)
    243   1.1  mrg 	lfd f30,-16(r11)
    244   1.1  mrg 	mtcr r0			/* restore the saved cr.  */
    245   1.1  mrg 	lwz r0, 8(r11)		/* Pick up the 'real' return address.  */
    246   1.1  mrg 	lfd f31,-8(r11)
    247   1.1  mrg 	mtctr r0		/* exception-handler ret. address  */
    248   1.1  mrg 	add r1,r11,r7		/* set SP to original value + R7 offset  */
    249   1.1  mrg 	bctr
    250   1.1  mrg #endif
    251   1.1  mrg /* we should never be called on ppc64 for this ... */
    252   1.1  mrg /* Done.  */
    253