arch/alpha/lib/memcpy.c
Source file repositories/reference/linux-study-clean/arch/alpha/lib/memcpy.c
File Facts
- System
- Linux kernel
- Corpus path
arch/alpha/lib/memcpy.c- Extension
.c- Size
- 4130 bytes
- Lines
- 167
- Domain
- Architecture Layer
- Bucket
- arch/alpha
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
Dependency Surface
linux/types.hlinux/export.hlinux/string.h
Detected Declarations
function Copyrightfunction loadfunction __memcpy_unaligned_dnfunction downfunction __memcpy_aligned_dnfunction memcpyexport memcpy
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/alpha/lib/memcpy.c
*
* Copyright (C) 1995 Linus Torvalds
*/
/*
* This is a reasonably optimized memcpy() routine.
*/
/*
* Note that the C code is written to be optimized into good assembly. However,
* at this point gcc is unable to sanely compile "if (n >= 0)", resulting in a
* explicit compare against 0 (instead of just using the proper "blt reg, xx" or
* "bge reg, xx"). I hope alpha-gcc will be fixed to notice this eventually..
*/
#include <linux/types.h>
#include <linux/export.h>
#include <linux/string.h>
/*
* This should be done in one go with ldq_u*2/mask/stq_u. Do it
* with a macro so that we can fix it up later..
*/
#define ALIGN_DEST_TO8_UP(d,s,n) \
while (d & 7) { \
if (n <= 0) return; \
n--; \
*(char *) d = *(char *) s; \
d++; s++; \
}
#define ALIGN_DEST_TO8_DN(d,s,n) \
while (d & 7) { \
if (n <= 0) return; \
n--; \
d--; s--; \
*(char *) d = *(char *) s; \
}
/*
* This should similarly be done with ldq_u*2/mask/stq. The destination
* is aligned, but we don't fill in a full quad-word
*/
#define DO_REST_UP(d,s,n) \
while (n > 0) { \
n--; \
*(char *) d = *(char *) s; \
d++; s++; \
}
#define DO_REST_DN(d,s,n) \
while (n > 0) { \
n--; \
d--; s--; \
*(char *) d = *(char *) s; \
}
/*
* This should be done with ldq/mask/stq. The source and destination are
* aligned, but we don't fill in a full quad-word
*/
#define DO_REST_ALIGNED_UP(d,s,n) DO_REST_UP(d,s,n)
#define DO_REST_ALIGNED_DN(d,s,n) DO_REST_DN(d,s,n)
/*
* This does unaligned memory copies. We want to avoid storing to
* an unaligned address, as that would do a read-modify-write cycle.
* We also want to avoid double-reading the unaligned reads.
*
* Note the ordering to try to avoid load (and address generation) latencies.
*/
static inline void __memcpy_unaligned_up (unsigned long d, unsigned long s,
long n)
{
ALIGN_DEST_TO8_UP(d,s,n);
n -= 8; /* to avoid compare against 8 in the loop */
if (n >= 0) {
unsigned long low_word, high_word;
__asm__("ldq_u %0,%1":"=r" (low_word):"m" (*(unsigned long *) s));
do {
unsigned long tmp;
__asm__("ldq_u %0,%1":"=r" (high_word):"m" (*(unsigned long *)(s+8)));
n -= 8;
__asm__("extql %1,%2,%0"
:"=r" (low_word)
:"r" (low_word), "r" (s));
__asm__("extqh %1,%2,%0"
:"=r" (tmp)
:"r" (high_word), "r" (s));
Annotation
- Immediate include surface: `linux/types.h`, `linux/export.h`, `linux/string.h`.
- Detected declarations: `function Copyright`, `function load`, `function __memcpy_unaligned_dn`, `function down`, `function __memcpy_aligned_dn`, `function memcpy`, `export memcpy`.
- Atlas domain: Architecture Layer / arch/alpha.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.