;! HP-PA strrchr ;! Copyright (C) 2016 Free Software Foundation, Inc. .text .export strrchr .balign 16 strrchr: .proc .callinfo frame=0,no_calls .entry ;! Compute the number of bytes required to align the pointer. ;! Multiply by 3, giving us 6 insns per entry to work with. ldo -1(%r26), %r20 extrw,u %r25, 31, 8, %r25 extrw,u %r20, 31, 2, %r20 shladd,l %r20, 1, %r20, %r20 blr %r20, %r0 ;! Begin by assuming that C is not present. ldi 0, %r28 ;! ptr % 4 == 1 ldb 0(%r26), %r20 cmpclr,<> %r25, %r20, %r0 copy %r26, %r28 cmpclr,<> %r0, %r20, %r0 bv,n 0(%r2) ldo 1(%r26), %r26 ;! ptr % 4 == 2 ldb 0(%r26), %r20 cmpclr,<> %r25, %r20, %r0 copy %r26, %r28 cmpclr,<> %r0, %r20, %r0 bv,n 0(%r2) ldo 1(%r26), %r26 ;! ptr % 4 == 3 ldb 0(%r26), %r20 cmpclr,<> %r25, %r20, %r0 copy %r26, %r28 cmpclr,<> %r0, %r20, %r0 bv,n 0(%r2) ldo 1(%r26), %r26 ;! ptr % 4 == 0 ldw,ma 4(%r26), %r20 copy %r25, %r24 depw %r24, 23, 8, %r24 depw %r24, 15, 16, %r24 ;! Main loop. 0: ;; Test for a NUL terminator within the word and exit if found. uxor,nbz %r0, %r20, %r0 b,n 1f ;; Test for C within the word. If not found, loop and load the ;; next word in the delay slot. If found, load the next word ;; now anyway, since we know that we havn't seen end-of-string. copy %r20, %r21 uxor,sbz %r24, %r20, %r0 b 0b ldw,ma 4(%r26), %r20 ;; Found C within the "current" word. Note that it is now in %r21, ;; and the address for the beginning of that word is now -8(%r26), ;; since we have incremented the pointer twice since the load. extrw,u %r21, 7, 8, %r22 cmpclr,<> %r25, %r22, %r0 ldo -8(%r26), %r28 extrw,u %r21, 15, 8, %r22 cmpclr,<> %r25, %r22, %r0 ldo -7(%r26), %r28 extrw,u %r21, 23, 8, %r22 cmpclr,<> %r25, %r22, %r0 ldo -6(%r26), %r28 extrw,u %r21, 31, 8, %r22 cmpclr,<> %r25, %r22, %r0 ldo -5(%r26), %r28 b,n 0b ;! Found NUL somewhere in with word in %r20, loaded from -4(%r26). ;! Test each byte in sequence. 1: extrw,u %r20, 7, 8, %r21 cmpclr,<> %r25, %r21, %r0 ldo -4(%r26), %r28 cmpclr,<> %r0, %r21, %r0 bv,n 0(%r2) extrw,u %r20, 15, 8, %r21 cmpclr,<> %r25, %r21, %r0 ldo -3(%r26), %r28 cmpclr,<> %r0, %r21, %r0 bv,n 0(%r2) extrw,u %r20, 23, 8, %r21 cmpclr,<> %r25, %r21, %r0 ldo -2(%r26), %r28 cmpclr,<> %r0, %r21, %r0 bv,n 0(%r2) ;; Having checked the others, the last byte must be NUL. ;; Do check for the unusual case of C == NUL. cmpclr,<> %r25, %r0, %r0 ldo -1(%r26), %r28 bv,n 0(%r2) .exit .procend