OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-newlib/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [hppa/] [strcat.S] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 jlechner
/*
2
 *  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
3
 *
4
 *  To anyone who acknowledges that this file is provided "AS IS"
5
 *  without any express or implied warranty:
6
 *      permission to use, copy, modify, and distribute this file
7
 *  for any purpose is hereby granted without fee, provided that
8
 *  the above copyright notice and this notice appears in all
9
 *  copies, and that the name of Hewlett-Packard Company not be
10
 *  used in advertising or publicity pertaining to distribution
11
 *  of the software without specific, written prior permission.
12
 *  Hewlett-Packard Company makes no representations about the
13
 *  suitability of this software for any purpose.
14
 */
15
 
16
/* HPUX_ID:     @(#) $Revision: 1.1 $   */
17
/*
18
 * strcat(s1, s2)
19
 *
20
 * Concatenate s2 on the end of s1.  S1's space must be large enough.
21
 * Return s1.
22
 */
23
#include "DEFS.h"
24
 
25
#define d_addr  r26
26
#define s_addr  r25
27
#define tmp6    r24
28
#define tmp1    r19
29
#define tmp2    r20
30
#define tmp3    r21
31
#define tmp4    r22
32
#define tmp5    arg3
33
#define save    r1
34
 
35
 
36
ENTRY(strcat)
37
 
38
        comb,=          r0,s_addr,done  /* quit if s2=NULL */
39
        copy      d_addr,ret0          /* The return value is the value of d_addr. DELAY SLOT*/
40
 
41
/* First look for end of s1 (d_addr) */
42
 
43
        extru       d_addr,31,2,tmp1   /* Extract the low two bits of the dest address. */
44
        combt,=         tmp1,r0,dont_mask
45
        dep             0,31,2,d_addr   /*set word alignment */
46
        ldwm            4(d_addr),tmp2
47
        sh3add          tmp1,r0,save    /* build mask based on tmp1 */
48
        mtctl           save,11
49
        zvdepi          -2,32,save
50
        or              save,tmp2,tmp2
51
        uxor,nbz        tmp2,r0,save
52
search:
53
        b,n             found_end       /* nullified under uxor conditions above and below */
54
dont_mask:
55
        ldwm            4(d_addr),tmp2
56
        comib,tr        r0,r0,search
57
        uxor,nbz        tmp2,r0,save
58
 
59
found_end:                              /* at this point d_addr points to word */
60
        extru,<>        save,7,8,r0     /* following word with null */
61
        addib,tr,n      -4,d_addr,begin_copy    /*set d_addr to end of s1 */
62
        extru,<>        save,15,8,r0
63
        addib,tr,n      -3,d_addr,begin_copy
64
        extru,<>        save,23,8,r0
65
        addi            -1,d_addr,d_addr
66
        addi            -1,d_addr,d_addr
67
 
68
 
69
begin_copy:
70
 
71
        extru       s_addr,31,2,tmp1   /* Extract the low two bits of the source address. */
72
        extru       d_addr,31,2,tmp6   /* Extract the low two bits of the destination address. */
73
        sub,=       tmp6,tmp1,tmp3     /* Compute the shift quantity and don't branch if tmp6=tmp1. */
74
        b           not_aligned        /* Not_aligned says that shifts Will be needed. */
75
        dep         0,31,2,s_addr      /* Compute the word address of the source.  DELAY SLOT. */
76
/* aligned */
77
 
78
        combt,=         tmp6,r0,skip_mask
79
        ldwm            4(0,s_addr),tmp1   /* tmp1 = *s_addr   s_addr += 4 (DELAY SLOT) */
80
        sh3add          tmp6,r0,save
81
        mtctl           save,r11
82
        zvdepi          -2,32,save
83
        or              save,tmp1,tmp1
84
        uxor,nbz        tmp1,r0,save
85
        b,n             first_null      /* special case: null in first word */
86
        b,n             skip_mask2
87
 
88
chunks:
89
        b,n             null_found      /* delay slot for uxor below */
90
 
91
skip_mask2:
92
        stbys,b,m       tmp1,4(d_addr)
93
        ldwm            4(s_addr),tmp1
94
skip_mask:
95
        comib,tr        0,0,chunks
96
        uxor,nbz        tmp1,r0,save
97
 
98
/* Begin non_aligned code.  */
99
 
100
not_aligned:
101
        sh3add,>=       tmp3,r0,tmp4        /* compute the shift amt.and skip load if tmp6 > tmp1. */
102
        ldwm            4(0,s_addr),tmp1    /* load up the first word from the source. tmp1 = *s_addr++ */
103
        ldwm            4(0,s_addr),tmp2    /* get either first or second word from source.  */
104
        combt,=         tmp6,r0,chunk2      /* don't mask if whole word is valid */
105
        mtctl           tmp4,11             /* load the shift count into cr11 = shift count register. */
106
        vshd            tmp1,tmp2,tmp3      /* position data !  (delay slot) */
107
        sh3add          tmp6,r0,save        /* setup r1 */
108
        mtctl           save,r11            /* set-up cr11 for mask */
109
        zvdepi          -2,32,save
110
        or              save, tmp3, tmp3
111
        uxor,nbz        tmp3,r0,save
112
        b,n             first_null2
113
        b               did_mask
114
        mtctl           tmp4,11            /* re-load the shift count into cr11 */
115
 
116
chunk2:
117
        vshd            tmp1,tmp2,tmp3
118
        uxor,nbz        tmp3, r0, save
119
        b,n             null_found
120
did_mask:
121
        stbys,b,m       tmp3,4(0,d_addr)    /* store !  */
122
 
123
        ldwm            4(0,s_addr),tmp1    /* get next word !  */
124
        vshd            tmp2,tmp1,tmp3      /* position data !  */
125
        uxor,nbz        tmp3, r0, save
126
        b,n             null_found
127
        stwm            tmp3,4(d_addr)
128
        comib,tr        0,0,chunk2
129
        ldwm            4(s_addr),tmp2
130
 
131
 
132
null_found:                             /* adjust d_addr and store final word */
133
 
134
        extru,<>        save,7,8,r0
135
        addib,tr,n      1,d_addr,store_final
136
        extru,<>        save,15,8,r0
137
        addib,tr,n      2,d_addr,store_final
138
        extru,<>        save,23,8,r0
139
        addib,tr        3,d_addr,store_final2
140
        bv              0(r2)
141
        stw             save,0(d_addr)
142
 
143
store_final:
144
        bv              0(r2)
145
store_final2:
146
        stbys,e         save,0(d_addr)  /* delay slot */
147
 
148
first_null:                     /* null found in first word of aligned (wrt d_addr) */
149
        addi            -4,s_addr,s_addr
150
        ldbx            tmp6(s_addr),tmp4
151
        add             tmp6,s_addr,s_addr
152
        comib,=         0,tmp4,done
153
        stbs,ma         tmp4,1(d_addr)
154
        ldbs            1(s_addr),tmp4
155
        comib,=         0,tmp4,done
156
        stbs,ma         tmp4,1(d_addr)
157
        bv              0(r2)           /* done */
158
        stbs            0,0(d_addr)
159
 
160
first_null2:    /* null found in first word of non-aligned (wrt d_addr) */
161
        addibt,=        -1,tmp6,check3  /* check last 3 bytes of word */
162
        extru           save,15,8,tmp4
163
        addibt,=,n      -1,tmp6,check2  /* check last 2 bytes */
164
        bv              0(r2)
165
        stbys,b         save, 0(d_addr)
166
 
167
check3:
168
        combt,=         tmp4,r0,done
169
        stbs,ma         tmp4,1(d_addr)
170
check2:
171
        extru,<>        save,23,8,tmp4
172
        bv              0(r2)
173
        stbs,ma         tmp4,1(d_addr)
174
        bv              0(r2)
175
        stbs            r0,0(d_addr)
176
 
177
done:
178
EXIT(strcat)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.