#++ # # Copyright (c) 1993 by # Digital Equipment Corporation, Maynard, MA # # This software is furnished under a license and may be used and copied # only in accordance with the terms of such license and with the # inclusion of the above copyright notice. This software or any other # copies thereof may not be provided or otherwise made available to any # other person. No title to and ownership of the software is hereby # transferred. # # The information in this software is subject to change without notice # and should not be construed as a commitment by Digital Equipment # Corporation. # # Digital assumes no responsibility for the use or reliability of its # software on equipment which is not supplied by Digital. # # Facility: # # GEM/OTS - GEM compiler system support library # # Abstract: # # OTS character string support, Alpha version # # Authors: # # Kent Glossop # # void ots_translate(char *dst, long dstlen, char *src, char table[256]); # # Translates a string using a translation table. Handles overlap. # # Special conventions: No stack space, r16-r21 and r26-r28 ONLY, # no linkage pointer required. # (Warning: The auto-loader potentially takes some regs across # the call if this is being used in a shared lib. environment.) # # Modification history: # # 006 13 Nov 1992 KDG Initial non-tailored assembly version, # replacing BLISS -005 # # 007 26 Jan 1993 KDG Add underscore #-- #include "ots_defs.hs" # r16 destination address # r17 length # r18 source address # r19 table address # r20,r21,r27,r28 scratch # r26 return address # .globl _OtsStringTranslate .ent _OtsStringTranslate _OtsStringTranslate: .set noat .set noreorder .frame sp,0,r26 # sort out which case to use addq r18, r17, r27 # get end address of source + 1 for overlap check cmpult r18, r16, r28 # true if src at lower addr than dest (note trans to self is not a "slow" case) cmpult r16, r27, r27 # true if dst starts before end of src beq r17, done # don't touch memory if length=0 and r27, r28, r28 # does dst have bad overlap with src? blbs r28, overlap # go handle poorly overlapping src/dst # simple forward loop case (~16 cycles/byte EV4) # (length is presumed to be at least 1) subq r18, 1, r18 # one before the beginning of the source subq r16, 1, r16 # one before the beginning of the destination forward_loop: ldq_u r20, 1(r18) # load the qw containing the source lda r18, 1(r18) # bump the source pointer ldq_u r21, 1(r16) # load the qw containing the destination lda r16, 1(r16) # bump the destination pointer extbl r20 ,r18, r20 # get the byte to translate addq r19, r20, r20 # get the address of the translation ldq_u r27, (r20) # load the translation subq r17, 1, r17 # decrement length mskbl r21, r16, r21 # clear the bits in the destination extbl r27, r20, r27 # extract the translation insbl r27, r16, r27 # position for insertion bis r27, r21, r21 # merge into the destination stq_u r21, (r16) # store back bgt r17, forward_loop # do another if there done: ret r31, (r26) nop #.align 3 # bad overlap case (~16 cycles/byte EV4, 11c/byte EV5) # (length is presumed to be at least 1) overlap: addq r17, r18, r18 # one past the end of the source addq r17, r16, r16 # one past the end of the destination backward_loop: ldq_u r20, -1(r18) # load the qw containing the source lda r18, -1(r18) # bump the source pointer ldq_u r21, -1(r16) # load the qw containing the destination lda r16, -1(r16) # bump the destination pointer extbl r20 ,r18, r20 # get the byte to translate addq r19, r20, r20 # get the address of the translation ldq_u r27, (r20) # load the translation subq r17, 1, r17 # decrement length mskbl r21, r16, r21 # clear the bits in the destination extbl r27, r20, r27 # extract the translation insbl r27, r16, r27 # position for insertion bis r27, r21, r21 # merge into the destination stq_u r21, (r16) # store back bgt r17, backward_loop # do another if there ret r31, (r26) .set at .set reorder .end _OtsStringTranslate