Home | History | Annotate | Line # | Download | only in ibm4xx
4xx_locore.S revision 1.1.2.3
      1 /*	$NetBSD: 4xx_locore.S,v 1.1.2.3 2002/12/19 15:52:19 thorpej Exp $	*/
      2 
      3 /*
      4  * Copyright 2001 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *      This product includes software developed for the NetBSD Project by
     20  *      Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 /*
     39  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
     40  * Copyright (C) 1995, 1996 TooLs GmbH.
     41  * All rights reserved.
     42  *
     43  * Redistribution and use in source and binary forms, with or without
     44  * modification, are permitted provided that the following conditions
     45  * are met:
     46  * 1. Redistributions of source code must retain the above copyright
     47  *    notice, this list of conditions and the following disclaimer.
     48  * 2. Redistributions in binary form must reproduce the above copyright
     49  *    notice, this list of conditions and the following disclaimer in the
     50  *    documentation and/or other materials provided with the distribution.
     51  * 3. All advertising materials mentioning features or use of this software
     52  *    must display the following acknowledgement:
     53  *	This product includes software developed by TooLs GmbH.
     54  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     55  *    derived from this software without specific prior written permission.
     56  *
     57  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     58  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     59  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     60  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     61  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     62  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     63  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     64  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     65  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     66  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     67  */
     68 
     69 /*
     70  * This is not a standalone file. To use it, #inlcude it at
     71  * the end of your port's locore.S
     72  */
     73 
     74 /*
     75  * Taken straight from Walnut's locore.S, with the following attribution:
     76  *	$OpenBSD: locore.S,v 1.4 1997/01/26 09:06:38 rahnds Exp $
     77  */
     78 
     79 /*
     80  * No processes are runnable, so loop waiting for one.
     81  * Separate label here for accounting purposes.
     82  * When we get here, interrupts are off (MSR[EE]=0) and sched_lock is held.
     83  */
     84 ASENTRY(Idle)
     85 	lis	8,_C_LABEL(sched_whichqs)@ha
     86 	lwz	9,_C_LABEL(sched_whichqs)@l(8)
     87 
     88 	or.	9,9,9
     89 	bne-	.Lsw1			/* at least one queue non-empty */
     90 
     91 	wrteei	1			/* reenable ints again */
     92 
     93 /* May do some power saving here? */
     94 /* Check if we can use power saving mode */
     95 	lis	8,_C_LABEL(powersave)@ha
     96 	lwz	9,_C_LABEL(powersave)@l(8)
     97 
     98 	or.	9,9,9
     99 	beq	1f
    100 
    101 	/* TODO:  Enter power saving mode here */
    102 1:
    103 
    104 	wrteei	0	/* disable interrupts while manipulating runque */
    105 
    106 	b	_ASM_LABEL(Idle)
    107 
    108 /*
    109  * switch_exit(struct lwp *l)
    110  * switch_exit gets called from cpu_exit to complete the exit procedure.
    111  */
    112 ENTRY(switch_lwp_exit)
    113 /* First switch to the idle pcb/kernel stack */
    114 	lis	6,idle_u@ha
    115 	lwz	6,idle_u@l(6)
    116 	lis	7,_C_LABEL(curpcb)@ha
    117 	stw	6,_C_LABEL(curpcb)@l(7)
    118 	addi	1,6,USPACE-16		/* 16 bytes are reserved at stack top */
    119 	/*
    120 	 * Schedule the vmspace and stack to be freed (the proc arg is
    121 	 * already in r3).
    122 	 */
    123 	bl	_C_LABEL(lwp_exit2)
    124 
    125 	b	finish_switch_exit
    126 
    127 /*
    128  * switch_exit(struct lwp *l)
    129  * switch_exit gets called from cpu_exit to complete the exit procedure.
    130  */
    131 ENTRY(switch_exit)
    132 /* First switch to the idle pcb/kernel stack */
    133 	lis	6,idle_u@ha
    134 	lwz	6,idle_u@l(6)
    135 	lis	7,_C_LABEL(curpcb)@ha
    136 	stw	6,_C_LABEL(curpcb)@l(7)
    137 	addi	1,6,USPACE-16		/* 16 bytes are reserved at stack top */
    138 	/*
    139 	 * Schedule the vmspace and stack to be freed (the proc arg is
    140 	 * already in r3).
    141 	 */
    142 	bl	_C_LABEL(exit2)
    143 
    144 finish_switch_exit:
    145 /* Fall through to cpu_switch to actually select another proc */
    146 	li	3,0			/* indicate exited process */
    147 
    148 /*
    149  * void cpu_switch(struct lwp *l)
    150  * Find a runnable process and switch to it.
    151  */
    152 /* XXX noprofile?  --thorpej (at) netbsd.org */
    153 ENTRY(cpu_switch)
    154 	mflr	0			/* save lr */
    155 	stw	0,4(1)
    156 	stwu	1,-16(1)
    157 	stw	31,12(1)
    158 	stw	30,8(1)
    159 
    160 	mr	30,3
    161 	lis	3,_C_LABEL(curlwp)@ha
    162 	xor	31,31,31
    163 	stw	31,_C_LABEL(curlwp)@l(3) /* Zero to not accumulate cpu time */
    164 	lis	3,_C_LABEL(curpcb)@ha
    165 	lwz	31,_C_LABEL(curpcb)@l(3)
    166 
    167 	xor	3,3,3
    168 	bl	_C_LABEL(lcsplx)
    169 	stw	3,PCB_SPL(31)		/* save spl */
    170 
    171 	wrteei	0			/* disable interrupts while manipulating runque */
    172 
    173 /* Find a new process */
    174 	lis	8,_C_LABEL(sched_whichqs)@ha
    175 	lwz	9,_C_LABEL(sched_whichqs)@l(8)
    176 
    177 	or.	9,9,9
    178 	beq-	_ASM_LABEL(Idle)	/* all queues empty */
    179 .Lsw1:
    180 	cntlzw	10,9
    181 	lis	4,_C_LABEL(sched_qs)@ha
    182 	addi	4,4,_C_LABEL(sched_qs)@l
    183 	slwi	3,10,3
    184 	add	3,3,4			/* select queue */
    185 
    186 	lwz	31,L_FORW(3)		/* unlink first proc from queue */
    187 	lwz	4,L_FORW(31)
    188 	stw	4,L_FORW(3)
    189 	stw	3,L_BACK(4)
    190 
    191 	cmpl	0,3,4			/* queue empty? */
    192 	bne	1f
    193 
    194 	lis	3,0x80000000@h
    195 	srw	3,3,10
    196 	andc	9,9,3
    197 	stw	9,_C_LABEL(sched_whichqs)@l(8) /* mark it empty */
    198 
    199 1:
    200 	/* just did this resched thing */
    201 	xor	3,3,3
    202 	lis	4,_C_LABEL(want_resched)@ha
    203 	stw	3,_C_LABEL(want_resched)@l(4)
    204 
    205 	stw	3,L_BACK(31)		/* probably superfluous */
    206 
    207 	/* Process now running on a processor. */
    208 	li	3,LSONPROC		/* l->l_stat = LSONPROC */
    209 	stw	3,L_STAT(31)
    210 
    211 	/* record new process */
    212 	lis	4,_C_LABEL(curlwp)@ha
    213 	stw	31,_C_LABEL(curlwp)@l(4)
    214 
    215 	wrteei	1			/* Now we can interrupt again */
    216 
    217 	li	3,0			/* if it's the same lwp, return 0 */
    218 	cmpl	0,31,30			/* is it the same process? */
    219 	beq	switch_return
    220 
    221 	or.	30,30,30		/* old process was exiting? */
    222 	beq	switch_exited
    223 
    224 #ifndef PPC_IBM4XX
    225 	mfsr	10,USER_SR		/* save USER_SR for copyin/copyout */
    226 #else
    227 	li	10,0			/* no SR for 4xx CPUs */
    228 #endif
    229 	mfcr	11			/* save cr */
    230 	mr	12,2			/* save r2 */
    231 	stwu	1,-SFRAMELEN(1)		/* still running on old stack */
    232 	stmw	10,8(1)
    233 	lwz	3,L_ADDR(30)
    234 	stw	1,PCB_SP(3)		/* save SP */
    235 
    236 switch_exited:
    237 	wrteei	0			/* disable interrupts while actually switching */
    238 
    239 	/* indicate new pcb */
    240 	lwz	4,L_ADDR(31)
    241 	lis	5,_C_LABEL(curpcb)@ha
    242 	stw	4,_C_LABEL(curpcb)@l(5)
    243 
    244 	/* save real pmap pointer for spill fill */
    245 	lwz	5,PCB_PMR(4)
    246 	lis	6,_C_LABEL(curpm)@ha
    247 	stwu	5,_C_LABEL(curpm)@l(6)
    248 	stwcx.	5,0,6			/* clear possible reservation */
    249 
    250 	/* Switch to the new virtual space */
    251 	/* Do not have to do anything here. TLB PID gets updated on return from trap. */
    252 
    253 	lwz	1,PCB_SP(4)		/* get new procs SP */
    254 
    255 	wrteei	1			/* interrupts are okay again */
    256 
    257 	lmw	10,8(1)			/* get other regs */
    258 	lwz	1,0(1)			/* get saved SP */
    259 	mr	2,12			/* get saved r2 */
    260 	mtcr	11			/* get saved cr */
    261 	isync
    262 	li	3,1			/* switched lwps */
    263 
    264 switch_return:
    265 	mr	30,3			/* save return value */
    266 
    267 	lwz	3,PCB_SPL(4)
    268 	bl	_C_LABEL(lcsplx)
    269 
    270 0:
    271 	lis	3,_C_LABEL(curpm)@ha
    272 	addi	3,3,_C_LABEL(curpm)@l	/* Do we need a context? */
    273 	lwz	4,PM_CTX(3)
    274 	cmpwi	4,0
    275 #	mtspr	SPR_SPR0,4		/* Always keep the current ctx here */
    276 	mr	3,30
    277 	bne	1f
    278 	bl	_C_LABEL(ctx_alloc)
    279 	b	0b			/* Reload */
    280 1:
    281 	lwz	31,12(1)
    282 	lwz	30,8(1)
    283 	addi	1,1,16
    284 	lwz	0,4(1)
    285 	mtlr	0
    286 	blr
    287 
    288 /*
    289  * void cpu_preempt(struct lwp *current, struct lwp *new))
    290  * Find a runnable process and switch to it.
    291  */
    292 ENTRY(cpu_preempt)
    293 	mflr	0			/* save lr */
    294 	stw	0,4(1)
    295 	stwu	1,-20(1)
    296 	stw	31,16(1)
    297 	stw	30,12(1)
    298 	stw	29,8(1)
    299 
    300 	mr	30,3
    301 	mr	29,4
    302 	lis	3,_C_LABEL(curlwp)@ha
    303 	xor	31,31,31
    304 	stw	31,_C_LABEL(curlwp)@l(3) /* Zero to not accumulate cpu time */
    305 	lis	3,_C_LABEL(curpcb)@ha
    306 	lwz	31,_C_LABEL(curpcb)@l(3)
    307 
    308 	xor	3,3,3
    309 	bl	_C_LABEL(lcsplx)
    310 	stw	3,PCB_SPL(31)		/* save spl */
    311 
    312 	wrteei	0			/* disable interrupts while manipulating runque */
    313 
    314 /* Find a new process */
    315 	xor	3,3,3
    316 
    317 	mr	31,29			/* r31 = newlwp */
    318 	lwz	4,L_BACK(31)		/* r4 = newlwp->l_back */
    319 	stw	3,L_BACK(31)		/* newlwp->l_back = NULL */
    320 	lwz	3,L_FORW(31)		/* r3 = newlwp->l_forw */
    321 	stw	4,L_BACK(3)		/* r3->l_back = r4 */
    322 	stw	3,L_FORW(4)		/* r4->l_forw = r3 */
    323 
    324 	cmpl	0,4,3			/* queue empty? */
    325 	bne	1f
    326 
    327 	/* so now r31 is newlwp and r3/r4 are scratch again */
    328 
    329 	lis	8,_C_LABEL(sched_whichqs)@ha
    330 	lwz	4,_C_LABEL(sched_whichqs)@l(8)
    331 
    332 	lbz	3,L_PRIORITY(31)
    333 	li	9,2
    334 	srw	3,3,9			/* r3 = newlwp->l_priority / 4 */
    335 	li	9,1
    336 	slw	3,9,3			/* r3 = 1 << r3 */
    337 	andc	4,4,3			/* sched_whichqs &= ~r3 */
    338 	stw	4,_C_LABEL(sched_whichqs)@l(8) /* mark it empty */
    339 
    340 1:
    341 	/* just did this resched thing */
    342 	xor	3,3,3
    343 	lis	4,_C_LABEL(want_resched)@ha
    344 	stw	3,_C_LABEL(want_resched)@l(4)
    345 
    346 	stw	3,L_BACK(31)		/* probably superfluous */
    347 
    348 	/* Process now running on a processor. */
    349 	li	3,LSONPROC		/* l->l_stat = LSONPROC */
    350 	stw	3,L_STAT(31)
    351 
    352 	/* record new process */
    353 	lis	4,_C_LABEL(curlwp)@ha
    354 	stw	31,_C_LABEL(curlwp)@l(4)
    355 
    356 	wrteei	1			/* Now we can interrupt again */
    357 
    358 	cmpl	0,31,30			/* is it the same process? */
    359 	beq	preempt_return
    360 
    361 	or.	30,30,30		/* old process was exiting? */
    362 	beq	preempt_exited
    363 
    364 #ifndef PPC_IBM4XX
    365 	mfsr	10,USER_SR		/* save USER_SR for copyin/copyout */
    366 #else
    367 	li	10,0			/* no SR for 4xx CPUs */
    368 #endif
    369 	mfcr	11			/* save cr */
    370 	mr	12,2			/* save r2 */
    371 	stwu	1,-SFRAMELEN(1)		/* still running on old stack */
    372 	stmw	10,8(1)
    373 	lwz	3,L_ADDR(30)
    374 	stw	1,PCB_SP(3)		/* save SP */
    375 
    376 preempt_exited:
    377 	wrteei	0			/* disable interrupts while actually switching */
    378 
    379 	/* indicate new pcb */
    380 	lwz	4,L_ADDR(31)
    381 	lis	5,_C_LABEL(curpcb)@ha
    382 	stw	4,_C_LABEL(curpcb)@l(5)
    383 
    384 	/* save real pmap pointer for spill fill */
    385 	lwz	5,PCB_PMR(4)
    386 	lis	6,_C_LABEL(curpm)@ha
    387 	stwu	5,_C_LABEL(curpm)@l(6)
    388 	stwcx.	5,0,6			/* clear possible reservation */
    389 
    390 	/* Switch to the new virtual space */
    391 	/* Do not have to do anything here. TLB PID gets updated on return from trap. */
    392 
    393 	lwz	1,PCB_SP(4)		/* get new procs SP */
    394 
    395 	wrteei	1			/* interrupts are okay again */
    396 
    397 	lmw	10,8(1)			/* get other regs */
    398 	lwz	1,0(1)			/* get saved SP */
    399 	mr	2,12			/* get saved r2 */
    400 	mtcr	11			/* get saved cr */
    401 	isync
    402 
    403 preempt_return:
    404 	lwz	3,PCB_SPL(4)
    405 	bl	_C_LABEL(lcsplx)
    406 
    407 0:
    408 	lis	3,_C_LABEL(curpm)@ha
    409 	addi	3,3,_C_LABEL(curpm)@l	/* Do we need a context? */
    410 	lwz	4,PM_CTX(3)
    411 	cmpwi	4,0
    412 #	mtspr	SPR_SPR0,4		/* Always keep the current ctx here */
    413 	mr	3,30
    414 	bne	1f
    415 	bl	_C_LABEL(ctx_alloc)
    416 	b	0b			/* Reload */
    417 1:
    418 	lwz	31,16(1)
    419 	lwz	30,12(1)
    420 	lwz	29,8(1)
    421 	addi	1,1,20
    422 	lwz	0,4(1)
    423 	mtlr	0
    424 	blr
    425 
    426 
    427 /*
    428  * Child comes here at the end of a fork.
    429  * Return to userspace via the trap return path.
    430  */
    431 	.globl	_C_LABEL(fork_trampoline)
    432 _C_LABEL(fork_trampoline):
    433 	xor	3,3,3
    434 	bl	_C_LABEL(lcsplx)
    435 	mtlr	31
    436 	mr	3,30
    437 	blrl				/* jump indirect to r31 */
    438 	b	trapexit
    439 
    440 /*
    441  * Pull in common trap vector code.
    442  */
    443 #include <powerpc/ibm4xx/trap_subr.S>
    444 #include <powerpc/ibm4xx/4xx_trap_subr.S>
    445 
    446 /*
    447  * int setfault()
    448  *
    449  * Similar to setjmp to setup for handling faults on accesses to user memory.
    450  * Any routine using this may only call bcopy, either the form below,
    451  * or the (currently used) C code optimized, so it doesn't use any non-volatile
    452  * registers.
    453  */
    454 	.globl	_C_LABEL(setfault)
    455 _C_LABEL(setfault):
    456 	mflr	0
    457 	mfcr	12
    458 	lis	4,_C_LABEL(curpcb)@ha
    459 	lwz	4,_C_LABEL(curpcb)@l(4)
    460 	stw	3,PCB_FAULT(4)
    461 	stw	0,0(3)
    462 	stw	1,4(3)
    463 	stw	2,8(3)
    464 	stmw	12,12(3)
    465 	xor	3,3,3
    466 	blr
    467 
    468 	.globl	_C_LABEL(ppc4xx_reset)
    469 _C_LABEL(ppc4xx_reset):
    470 	mfspr	3,SPR_DBCR0
    471 	oris	3,r13,DBCR0_RST_SYSTEM@h
    472 	mtspr	SPR_DBCR0,3
    473 	ba	0
    474 
    475 #if 0
    476 /*
    477  * XXXX the following doesn't quite work right yet.
    478  */
    479 /*
    480  * void bcopy(const void *src, void *dst, size_t len);
    481  *
    482  * swap r3 and r4 and fall through to memcopy.
    483  */
    484 	.globl _C_LABEL(bcopy)
    485 _C_LABEL(bcopy):
    486 	mr	r0,r3
    487 	mr	r3,r4
    488 	mr	r4,r0
    489 	/* FALLTHROUGH */
    490 
    491 /*
    492  * void * memcpy(void *dst (r3), const void *src (r4), size_t len (r5));
    493  *
    494  * Copy memory (obviously)
    495  *
    496  * We will try to do data cache block aligned stores so we
    497  * can use block allocate and not have to read from the
    498  * destination.
    499  *
    500  * Register use:
    501  *
    502  *	r1		stack (of course)
    503  *	r3		dst
    504  *	r4		src
    505  *	r5		len
    506  *	r6		tmp
    507  *	r7		holds 32
    508  *	r8		holds dst
    509  *	r24-r31		block move regs
    510  *
    511  */
    512 
    513 ENTRY(memcpy)
    514 	stwu	r1,-(10*4)(r1)	/* Allocate some RAM to save 8 regs to. */
    515 	cmpwi	r5, 32		/* Less than 32 bytes ? */
    516 	stmw	r24,8(r1)	/* Save ALL regs (could be optimized) */
    517 
    518 	mr	r8,r3		/* save dst */
    519 	li	r7,32
    520 
    521 	dcbt	0,r4		/* Start bringing in cache line. */
    522 	blt	1f		/* Finish up */
    523 
    524 	neg	r6,r3		/* Find how far unaligned we are... */
    525 	andi.	r6,r6,31	/* Cache-align dest. */
    526 	mtxer	r6
    527 	sub	r5,r5,r6	/* subtract count */
    528 	lswx	r24,0,r4	/* Load some. */
    529 	add	r4,r4,r6
    530 	dcbt	0,r4		/* Fetch next line */
    531 	stswx	r24,0,r3	/* Store some */
    532 	add	r3,r3,r6
    533 	addic.	r6,r5,-32	/* Pre-decrement next line */
    534 	ble	1f		/* Less than 32-bytes? finishup */
    535 
    536 	/* Dest should not be cache line aligned. */
    537 	/* XXX need gas 2.11 to grok dcba insn */
    538 #ifdef GAS_2_11
    539 	dcba	0,r3		/* Allocate a line */
    540 #else
    541 	.long	0x7c001dec	/* dcba	0,r3 */
    542 #endif
    543 0:
    544 	dcbt	r7,r4		/* Bring in the next line, too */
    545 
    546 	lswi	r24,r4,32
    547 	addi	r4,r4,32	/* Inc src */
    548 	mr	r5,r6
    549 
    550 	addic.	r6,r5,-32
    551 	stswi	r24,r3,32
    552 	addi	r3,r3,32	/* Inc dst */
    553 #ifdef GAS_2_11
    554 	dcba	0,r3		/* Allocate another line */
    555 #else
    556 	.long	0x7c071dec	/* dcba	r7,r3 */
    557 #endif
    558 	bgt	0b
    559 1:
    560 	mtxer	r5		/* Store byte count */
    561 	lswx	r24,0,r4	/* Load up to 32 bytes */
    562 	stswx	r24,0,r3	/* Store up to 32 bytes */
    563 
    564 	mr	r3,r8		/* Return dst */
    565 
    566 	lmw	r24,8(r1)
    567 	addi	r1,r1,(10*4)
    568 	blr
    569 #endif
    570