/branches/dynload/kernel/arch/amd64/include/memstr.h |
---|
35,110 → 35,13 |
#ifndef KERN_amd64_MEMSTR_H_ |
#define KERN_amd64_MEMSTR_H_ |
/** Copy memory |
* |
* Copy a given number of bytes (3rd argument) |
* from the memory location defined by 2nd argument |
* to the memory location defined by 1st argument. |
* The memory areas cannot overlap. |
* |
* @param dst Destination |
* @param src Source |
* @param cnt Number of bytes |
* @return Destination |
*/ |
static inline void * memcpy(void * dst, const void * src, size_t cnt) |
{ |
unative_t d0, d1, d2; |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
asm volatile( |
"rep movsq\n\t" |
"movq %4, %%rcx\n\t" |
"andq $7, %%rcx\n\t" |
"jz 1f\n\t" |
"rep movsb\n\t" |
"1:\n" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
: "0" ((unative_t)(cnt / 8)), "g" ((unative_t)cnt), "1" ((unative_t) dst), "2" ((unative_t) src) |
: "memory"); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
return dst; |
} |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
/** Compare memory regions for equality |
* |
* Compare a given number of bytes (3rd argument) |
* at memory locations defined by 1st and 2nd argument |
* for equality. If bytes are equal function returns 0. |
* |
* @param src Region 1 |
* @param dst Region 2 |
* @param cnt Number of bytes |
* @return Zero if bytes are equal, non-zero otherwise |
*/ |
static inline int memcmp(const void * src, const void * dst, size_t cnt) |
{ |
unative_t d0, d1, d2; |
unative_t ret; |
asm ( |
"repe cmpsb\n\t" |
"je 1f\n\t" |
"movq %3, %0\n\t" |
"addq $1, %0\n\t" |
"1:\n" |
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2) |
: "0" (0), "1" (src), "2" (dst), "3" ((unative_t)cnt) |
); |
return ret; |
} |
/** Fill memory with words |
* Fill a given number of words (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of words |
* @param x Value to fill |
*/ |
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
unative_t d0, d1; |
asm volatile ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((unative_t)cnt), "2" (x) |
: "memory" |
); |
} |
/** Fill memory with bytes |
* Fill a given number of bytes (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of bytes |
* @param x Value to fill |
*/ |
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
unative_t d0, d1; |
asm volatile ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((unative_t)cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/** @} |
/branches/dynload/kernel/arch/amd64/src/asm_utils.S |
---|
65,6 → 65,8 |
.global get_cycle |
.global read_efer_flag |
.global set_efer_flag |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
71,6 → 73,14 |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
# Wrapper for generic memsetb |
memsetb: |
jmp _memsetb |
# Wrapper for generic memsetw |
memsetw: |
jmp _memsetw |
#define MEMCPY_DST %rdi |
#define MEMCPY_SRC %rsi |
#define MEMCPY_SIZE %rdx |
/branches/dynload/kernel/arch/mips32/include/atomic.h |
---|
63,7 → 63,7 |
" sc %0, %1\n" |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
" nop\n" |
: "=r" (tmp), "=m" (val->count), "=r" (v) |
: "=&r" (tmp), "=m" (val->count), "=&r" (v) |
: "i" (i), "i" (0) |
); |
/branches/dynload/kernel/arch/ia32/include/memstr.h |
---|
35,116 → 35,13 |
#ifndef KERN_ia32_MEMSTR_H_ |
#define KERN_ia32_MEMSTR_H_ |
/** Copy memory |
* |
* Copy a given number of bytes (3rd argument) |
* from the memory location defined by 2nd argument |
* to the memory location defined by 1st argument. |
* The memory areas cannot overlap. |
* |
* @param dst Destination |
* @param src Source |
* @param cnt Number of bytes |
* @return Destination |
*/ |
static inline void * memcpy(void * dst, const void * src, size_t cnt) |
{ |
unative_t d0, d1, d2; |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
asm volatile( |
/* copy all full dwords */ |
"rep movsl\n\t" |
/* load count again */ |
"movl %4, %%ecx\n\t" |
/* ecx = ecx mod 4 */ |
"andl $3, %%ecx\n\t" |
/* are there last <=3 bytes? */ |
"jz 1f\n\t" |
/* copy last <=3 bytes */ |
"rep movsb\n\t" |
/* exit from asm block */ |
"1:\n" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
: "0" ((unative_t) (cnt / 4)), "g" ((unative_t) cnt), "1" ((unative_t) dst), "2" ((unative_t) src) |
: "memory"); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
return dst; |
} |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
/** Compare memory regions for equality |
* |
* Compare a given number of bytes (3rd argument) |
* at memory locations defined by 1st and 2nd argument |
* for equality. If bytes are equal function returns 0. |
* |
* @param src Region 1 |
* @param dst Region 2 |
* @param cnt Number of bytes |
* @return Zero if bytes are equal, non-zero otherwise |
*/ |
static inline int memcmp(const void * src, const void * dst, size_t cnt) |
{ |
uint32_t d0, d1, d2; |
int ret; |
asm ( |
"repe cmpsb\n\t" |
"je 1f\n\t" |
"movl %3, %0\n\t" |
"addl $1, %0\n\t" |
"1:\n" |
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2) |
: "0" (0), "1" ((unative_t) src), "2" ((unative_t) dst), "3" ((unative_t) cnt) |
); |
return ret; |
} |
/** Fill memory with words |
* Fill a given number of words (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of words |
* @param x Value to fill |
*/ |
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
/** Fill memory with bytes |
* Fill a given number of bytes (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of bytes |
* @param x Value to fill |
*/ |
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia32/src/asm.S |
---|
37,6 → 37,8 |
.global paging_on |
.global enable_l_apic_in_msr |
.global interrupt_handlers |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_from_uspace_failover_address |
44,6 → 46,15 |
.global memcpy_to_uspace_failover_address |
# Wrapper for generic memsetb |
memsetb: |
jmp _memsetb |
# Wrapper for generic memsetw |
memsetw: |
jmp _memsetw |
#define MEMCPY_DST 4 |
#define MEMCPY_SRC 8 |
#define MEMCPY_SIZE 12 |