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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [hppa/] [strncpy.S] - Blame information for rev 407

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/*
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
 * strncpy(s1, s2, n)
19
 *
20
 * Copy s2 to s1, truncating or null-padding to always copy n bytes
21
 * return s1
22
 */
23
 
24
#include "DEFS.h"
25
 
26
#define d_addr  r26
27
#define s_addr  r25
28
#define count   r24
29
#define tmp1    r19
30
#define tmp2    r20
31
#define tmp3    r21
32
#define tmp4    r22
33
#define tmp5    arg3
34
#define save    r1
35
 
36
 
37
ENTRY(strncpy)
38
 
39
        combt,=   s_addr,r0,pad_null_bytes1     /* if s2==NULL then pad nulls and exit */
40
        copy      d_addr,ret0          /* The return value is defined to be the value of d_addr. DELAY SLOT*/
41
        addibt,<,n  -4,count,byteloop     /* If count is <= 4 don't get fancy.*/
42
 
43
        extru       s_addr,31,2,tmp1   /* Extract the low two bits of the source address.*/
44
        extru       d_addr,31,2,tmp5   /* Extract the low two bits of the destination address.*/
45
        add         count,tmp5,count   /* pre increment the count by the byte address so that the count is*/
46
        comb,<>       tmp5,tmp1,not_aligned /* branch if tmp5<>tmp1. */
47
        dep         0,31,2,s_addr      /* Compute the word address of the source.  DELAY SLOT.*/
48
/* aligned*/
49
        combt,=         tmp5,r0,skip_mask
50
        ldwm        4(0,s_addr),tmp1   /* tmp1 = *s_addr   s_addr += 4 (DELAY SLOT)*/
51
        sh3add          tmp5,r0,save    /* compute mask in save*/
52
        mtctl           save,11
53
        zvdepi          -2,32,save
54
        b               skip_mask       /* don't reload tmp1*/
55
        or              save,tmp1,tmp1  /* or mask with data*/
56
 
57
chunks:
58
        ldwm            4(0,s_addr),tmp1 /* get a word*/
59
 
60
skip_mask:
61
        uxor,nbz        tmp1,r0,save    /* check for null*/
62
        b,n             null1
63
        addibf,<        -4,count,chunks
64
        stbys,b,m   tmp1,4(0,d_addr)   /* store word (delay slot)*/
65
 
66
/* back_porch                              last word to store*/
67
         addibt,=,n  4,count,done       /* if count = 0 we're, of course, done !*/
68
         ldws        0(s_addr),tmp1     /* load up the back_porch*/
69
         add         d_addr,count,d_addr/* final store address  is +1 too high !*/
70
         sh3add         count,r0, save  /* setup right mask based on count*/
71
         mtctl          save,r11
72
         zvdepi         -2,32,save      /*save now has left-hand mask*/
73
         uaddcm         r0,save,save    /*form right hand mask */
74
         or             tmp1,save,tmp1  /*and insert data*/
75
         uxor,nbz       tmp1,r0,save    /* check for null*/
76
         b,n            null2
77
         bv             0(r2)
78
         stbys,e        tmp1,0(d_addr)  /* done */
79
 
80
/* Begin non_aligned code. */
81
not_aligned:
82
        sub,>=       tmp5,tmp1,tmp3     /* compute the shift amt.and skip load if tmp5 > tmp1.*/
83
        ldwm         4(0,s_addr),tmp1   /* load up the first word from the source. tmp1 = *s_addr++*/
84
        zdep         tmp3,28,29,tmp4    /* compute the number of bits to shift */
85
        mtctl        tmp4,11            /* load the shift count into cr11 = shift count register.*/
86
        addibt,<,n   -4,count,chkchnk2 /* first step in pre adjustment of count for looping.*/
87
 
88
        ldwm        4(0,s_addr),tmp2    /* get either first or second word from source. */
89
        combt,=         tmp5,r0,skip_mask2 /* don't mask if whole word is valid*/
90
        vshd        tmp1,tmp2,tmp3      /* position data !  (delay slot)*/
91
        sh3add          tmp5,r0,save    /* setup r1*/
92
        mtctl           save,r11        /* setup mask in save*/
93
        zvdepi          -2,32,save
94
        or              save, tmp3, tmp3
95
        mtctl           tmp4,11            /* re-load the shift count into cr11 */
96
        b               skip_mask2
97
        copy            r0, tmp5        /* zero out tmp5 so we don't try to mask again*/
98
 
99
chunk2:
100
        ldwm        4(0,s_addr),tmp2
101
        vshd        tmp1,tmp2,tmp3
102
 
103
skip_mask2:
104
        uxor,nbz        tmp3, r0, save
105
        b,n             null3
106
        stbys,b,m   tmp3,4(0,d_addr)    /* store ! */
107
 
108
        ldwm        4(0,s_addr),tmp1    /* get 2nd word ! */
109
        vshd        tmp2,tmp1,tmp3      /* position data ! */
110
        uxor,nbz        tmp3, r0, save
111
        b,n             null4
112
 
113
        addibf,<    -8,count,chunk2    /* If count is still >= 8 do another loop.*/
114
        stbys,b,m   tmp3,4(0,d_addr)    /* store !*/
115
 
116
chkchnk2:
117
        addibt,<,n  4,count,bp_0       /* if we don't have 4 bytes left then do the back porch (bp_0)*/
118
 
119
subchnk2: /* we have less than 8 chars to copy*/
120
 
121
        ldwm        4(0,s_addr),tmp2    /* get next word !*/
122
        combt,=         tmp5,r0,skip_mask3
123
        vshd        tmp1,tmp2,tmp3      /* position data !*/
124
        sh3add          tmp5,r0,save    /* setup r1*/
125
        mtctl           save,r11        /* setup mask in save*/
126
        zvdepi          -2,32,save
127
        or              save, tmp3, tmp3
128
        mtctl           tmp4,11         /* restore shift value again */
129
        copy            r0, tmp5        /* zero out tmp5 so we don't try to mask again*/
130
skip_mask3:
131
        uxor,nbz        tmp3,r0,save
132
        b,n             null4
133
        b               bp_1 /* we now have less than 4 bytes to move*/
134
        stbys,b,m   tmp3,4(0,d_addr)    /* store !*/
135
 
136
bp_0:
137
        copy        tmp1,tmp2           /* switch registers used in the shift process.*/
138
        addibt,<=,n  4,count,done        /* if count = -4 this implies that count = 0 -> done */
139
 
140
bp_1:
141
        ldwm        4(0,s_addr),tmp1    /* get final word !        */
142
        vshd        tmp2,tmp1,tmp3      /* position data !*/
143
        uxor,sbz        tmp3,r0,save    /* if some-byte-zero */
144
        b               no_null         /* don't goto no_null-find which null instead */
145
        add             d_addr,count,d_addr     /* get d_addr ready for stbys,e */
146
        extru,<>        save,7,8,r0
147
        b               found_null5
148
        copy            r0, tmp5
149
        extru,<>        save,15,8,r0
150
        b               found_null5
151
        ldil            0x1FE000,tmp5           /* setup mask (FF000000)*/
152
        extru,<>        save,23,8,r0
153
        b               found_null5
154
        ldil            0x1FFFE0,tmp5           /* setup mask (FFFF0000)*/
155
        ldo             -1(r0),tmp5             /* setup mask (FFFFFFFF)*/
156
found_null5:
157
        and             tmp3,tmp5,tmp3  /* zero out tmp5 based on mask in tmp5*/
158
no_null:
159
        bv              0(r2)           /* were done*/
160
        stbys,e     tmp3,0(0,d_addr)    /* store the data !*/
161
 
162
/* here we do ye old byte-at-a-time moves.*/
163
byteloop:
164
        addibt,=,n     4,count,done
165
        comb,=    0,s_addr,done
166
        stbs      r0,0(d_addr)          /* store null in case s_addr == NULL */
167
        ldbs,ma     1(s_addr),tmp1
168
encore:
169
        combt,=,n       tmp1,r0, pad_null_bytes1
170
        stbs,ma     tmp1,1(d_addr)
171
        addibf,=,n  -1,count,encore
172
        ldbs,ma     1(s_addr),tmp1
173
        b,n             done
174
 
175
pnb_1:
176
        addibt,=,n      4,count,done /* if count was already 0 then we're done*/
177
 
178
pad_null_bytes1:
179
        combt,=,n       count,r0,done   /* if count==0 then exit */
180
pad_null_bytes2:
181
        addibf,=        -1,count,pad_null_bytes2
182
        stbs,ma         r0,1(d_addr)
183
        b,n             done
184
 
185
pad_nulls:
186
        addibf,<=,n     -4,count,pad_nulls
187
        stwm            r0,4(d_addr)
188
        b,n             pnb_1
189
 
190
 
191
null1:
192
        extru,<>        save,7,8,r0
193
        b               found_null1
194
        copy            r0, tmp5
195
        extru,<>        save,15,8,r0
196
        b               found_null1
197
        ldil            0x1FE000,tmp5           /* setup mask (FF000000)*/
198
        extru,<>        save,23,8,r0
199
        b               found_null1
200
        ldil            0x1FFFE0,tmp5           /* setup mask (FFFF0000)*/
201
        ldo             -1(r0),tmp5             /* setup mask (FFFFFFFF)*/
202
found_null1:
203
        and             tmp1,tmp5,tmp1          /*zero out tmp1 according to mask*/
204
        b               pad_nulls               /* nullify remaining count bytes*/
205
        stbys,b,m       tmp1,4(0,d_addr)        /* first word (account for alignment)*/
206
 
207
 
208
null2:  /* back porch case. We have less than 4 bytes to go.*/
209
        extru,<>        save,7,8,r0     /* is null in 1st byte? */
210
        b               found_null2
211
        copy            r0, tmp5
212
        extru,<>        save,15,8,r0    /* is null in 2nd byte? */
213
        b               found_null2
214
        ldil            0x1FE000,tmp5           /* setup mask (FF000000)*/
215
        b               found_null2     /* null must be in 3rd byte */
216
        ldil            0x1FFFE0,tmp5           /* setup mask (FFFF0000)*/
217
found_null2:
218
        and             tmp1,tmp5,tmp1          /*zero out tmp1 according to mask*/
219
        bv              0(r2)                   /* we're done*/
220
        stbys,e         tmp1,0(0,d_addr)        /* last word (back porch)*/
221
 
222
null3:  /* not_aligned case where null is found in first of two words--adjust count*/
223
        extru,<>        save,7,8,r0
224
        b               found_null3
225
        copy            r0, tmp5
226
        extru,<>        save,15,8,r0
227
        b               found_null3
228
        ldil            0x1FE000,tmp5           /* setup mask (FF000000)*/
229
        extru,<>        save,23,8,r0
230
        b               found_null3
231
        ldil            0x1FFFE0,tmp5           /* setup mask (FFFF0000)*/
232
        ldo             -1(r0),tmp5             /* setup mask (FFFFFFFF)*/
233
found_null3:
234
        addi            4,count,count           /* fix count since null is in first of two words*/
235
        and             tmp3,tmp5,tmp3          /*zero out tmp3 according to mask*/
236
        b               pad_nulls               /* nullify remaining count bytes*/
237
        stbys,b,m       tmp3,4(d_addr)
238
 
239
null4:  /* not_aligned case where null is found in second of two words*/
240
        extru,<>        save,7,8,r0
241
        b               found_null4
242
        copy            r0, tmp5
243
        extru,<>        save,15,8,r0
244
        b               found_null4
245
        ldil            0x1FE000,tmp5           /* setup mask (FF000000)*/
246
        extru,<>        save,23,8,r0
247
        b               found_null4
248
        ldil            0x1FFFE0,tmp5           /* setup mask (FFFF0000)*/
249
        ldo             -1(r0),tmp5             /* setup mask (FFFFFFFF)*/
250
found_null4:
251
        and             tmp3,tmp5,tmp3          /*zero out tmp4 according to mask*/
252
        b               pad_nulls               /* nullify remaining count bytes*/
253
        stbys,b,m       tmp3,4(d_addr)
254
 
255
done:
256
EXIT(strncpy)

powered by: WebSVN 2.1.0

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