1/* 2 * Copyright 2005-2010 Analog Devices Inc. 3 * 4 * Licensed under the ADI BSD license or the GPL-2 (or later) 5 */ 6 7#include <linux/linkage.h> 8#include <asm/context.S> 9 10/* void *strncpy(char *dest, const char *src, size_t n); 11 * R0 = address (dest) 12 * R1 = address (src) 13 * R2 = size 14 * Returns a pointer (R0) to the destination string dest 15 * we do this by not changing R0 16 */ 17 18#ifdef CONFIG_STRNCPY_L1 19.section .l1.text 20#else 21.text 22#endif 23 24.align 2 25 26ENTRY(_strncpy) 27 CC = R2 == 0; 28 if CC JUMP 6f; 29 30 P2 = R2 ; /* size */ 31 P0 = R0 ; /* dst*/ 32 P1 = R1 ; /* src*/ 33 34 LSETUP (1f, 2f) LC0 = P2; 351: 36 R1 = B [P1++] (Z); 37 B [P0++] = R1; 38 CC = R1 == 0; 392: 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 */ 483: 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 60 R2 += -1; 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; 77 784: 79 LSETUP(5f, 5f) LC0; 805: 81 B [P0++] = R1; 826: 83 RTS; 84 85ENDPROC(_strncpy) 86