ref: e391b7ec8c0dc746a70725f3fc598def0419d1e6
dir: /sys/src/libc/riscv64/memset.s/
/* memset(void *p, int c, uintptr n) - clear vlongs */ TEXT memset(SB),$(3*XLEN) MOV R8, p+0(FP) MOV R8, R11 /* R11 is pointer */ MOVWU c+XLEN(FP), R12 /* R12 is char */ MOV n+(2*XLEN)(FP), R10 /* R10 is count. NB: uintptr */ ADD R10,R11, R13 /* R13 is end pointer */ /* * if not at least XLEN chars, * dont even mess around. * XLEN-1 chars to guarantee any * rounding up to a doubleword * boundary and XLEN characters * to get at least maybe one * full doubleword store. */ SLT $XLEN,R10, R8 BNE R8, out /* * turn R12 into a doubleword of characters */ AND $0xff, R12 SLL $8,R12, R8 OR R8, R12 SLL $16,R12, R8 OR R8, R12 SLL $32,R12, R8 OR R8, R12 /* * store one byte at a time until pointer * is aligned on a doubleword boundary */ l1: AND $(XLEN-1),R11, R8 BEQ R8, l2 MOVB R12, 0(R11) ADD $1, R11 JMP l1 /* * turn R10 into end pointer-(4*XLEN-1) * store 4*XLEN at a time while there's room */ l2: ADD $-(4*XLEN-1),R13, R10 l3: BGEU R10,R11, l4 MOV R12, 0(R11) MOV R12, XLEN(R11) MOV R12, (2*XLEN)(R11) MOV R12, (3*XLEN)(R11) ADD $(4*XLEN), R11 JMP l3 /* * turn R10 into end pointer-(XLEN-1) * store XLEN at a time while there's room */ l4: ADD $-(XLEN-1),R13, R10 l5: BGEU R10,R11, out MOV R12, 0(R11) ADD $XLEN, R11 JMP l5 /* * last loop, store byte at a time */ out: BGEU R13,R11, ret MOVB R12, 0(R11) ADD $1, R11 JMP out ret: MOV p+0(FP), R8 RET