Commit | Line | Data |
---|---|---|
479ba603 RG |
1 | /* |
2 | * Copyright 2005-2010 Analog Devices Inc. | |
3 | * | |
de450838 | 4 | * Licensed under the Clear BSD license or the GPL-2 (or later) |
479ba603 RG |
5 | */ |
6 | ||
7 | #include <linux/linkage.h> | |
648eee52 | 8 | #include <asm/context.S> |
479ba603 RG |
9 | |
10 | /* void *strncpy(char *dest, const char *src, size_t n); | |
11 | * R0 = address (dest) | |
12 | * R1 = address (src) | |
13 | * R2 = size | |
648eee52 RG |
14 | * Returns a pointer (R0) to the destination string dest |
15 | * we do this by not changing R0 | |
479ba603 RG |
16 | */ |
17 | ||
18 | #ifdef CONFIG_STRNCPY_L1 | |
19 | .section .l1.text | |
20 | #else | |
21 | .text | |
22 | #endif | |
23 | ||
24 | .align 2 | |
25 | ||
26 | ENTRY(_strncpy) | |
27 | CC = R2 == 0; | |
5ff6197f | 28 | if CC JUMP 6f; |
648eee52 RG |
29 | |
30 | P2 = R2 ; /* size */ | |
479ba603 RG |
31 | P0 = R0 ; /* dst*/ |
32 | P1 = R1 ; /* src*/ | |
33 | ||
648eee52 | 34 | LSETUP (1f, 2f) LC0 = P2; |
479ba603 RG |
35 | 1: |
36 | R1 = B [P1++] (Z); | |
37 | B [P0++] = R1; | |
648eee52 | 38 | CC = R1 == 0; |
479ba603 | 39 | 2: |
648eee52 RG |
40 | if CC jump 3f; |
41 | ||
42 | RTS; | |
43 | ||
44 | /* if src is shorter than n, we need to null pad bytes in dest | |
45 | * but, we can get here when the last byte is zero, and we don't | |
46 | * want to copy an extra byte at the end, so we need to check | |
47 | */ | |
479ba603 | 48 | 3: |
648eee52 RG |
49 | R2 = LC0; |
50 | CC = R2 | |
51 | if ! CC jump 6f; | |
52 | ||
53 | /* if the required null padded portion is small, do it here, rather than | |
54 | * handling the overhead of memset (which is OK when things are big). | |
55 | */ | |
56 | R3 = 0x20; | |
57 | CC = R2 < R3; | |
58 | IF CC jump 4f; | |
59 | ||
479ba603 | 60 | R2 += -1; |
648eee52 RG |
61 | |
62 | /* Set things up for memset | |
63 | * R0 = address | |
64 | * R1 = filler byte (this case it's zero, set above) | |
65 | * R2 = count (set above) | |
66 | */ | |
67 | ||
68 | I1 = R0; | |
69 | R0 = RETS; | |
70 | I0 = R0; | |
71 | R0 = P0; | |
72 | pseudo_long_call _memset, p0; | |
73 | R0 = I0; | |
74 | RETS = R0; | |
75 | R0 = I1; | |
76 | RTS; | |
479ba603 RG |
77 | |
78 | 4: | |
648eee52 RG |
79 | LSETUP(5f, 5f) LC0; |
80 | 5: | |
81 | B [P0++] = R1; | |
82 | 6: | |
479ba603 RG |
83 | RTS; |
84 | ||
85 | ENDPROC(_strncpy) |