lowercasing filenames, part3
[picodrive.git] / pico / misc_arm.s
diff --git a/pico/misc_arm.s b/pico/misc_arm.s
new file mode 100644 (file)
index 0000000..1ef2e58
--- /dev/null
@@ -0,0 +1,181 @@
+@ vim:filetype=armasm
+
+@ Generic memory routines.
+@ (c) Copyright 2007, Grazvydas "notaz" Ignotas
+
+
+.global memcpy16 @ unsigned short *dest, unsigned short *src, int count
+
+memcpy16:
+    eor     r3, r0, r1
+    tst     r3, #2
+    bne     mcp16_cant_align
+
+    tst     r0, #2
+    ldrneh  r3, [r1], #2
+    subne   r2, r2, #1
+    strneh  r3, [r0], #2
+
+    subs    r2, r2, #4
+    bmi     mcp16_fin
+
+mcp16_loop:
+    ldmia   r1!, {r3,r12}
+    subs    r2, r2, #4
+    stmia   r0!, {r3,r12}
+    bpl     mcp16_loop
+
+mcp16_fin:
+    tst     r2, #2
+    ldrne   r3, [r1], #4
+    strne   r3, [r0], #4
+    ands    r2, r2, #1
+    bxeq    lr
+
+mcp16_cant_align:
+    ldrh    r3, [r1], #2
+    subs    r2, r2, #1
+    strh    r3, [r0], #2
+    bne     mcp16_cant_align
+
+    bx      lr
+
+
+
+@ 0x12345678 -> 0x34127856
+@ r4=temp, lr=0x00ff00ff
+.macro bswap reg
+    and     r4,   \reg, lr
+    and     \reg, lr,   \reg, lsr #8
+    orr     \reg, \reg, r4,   lsl #8
+.endm
+
+
+@ dest must be halfword aligned, src can be unaligned
+.global memcpy16bswap @ unsigned short *dest, void *src, int count
+
+memcpy16bswap:
+    tst     r1, #1
+    bne     mcp16bs_cant_align2
+
+    eor     r3, r0, r1
+    tst     r3, #2
+    bne     mcp16bs_cant_align
+
+    tst     r0, #2
+    beq     mcp16bs_aligned
+    ldrh    r3, [r1], #2
+    sub     r2, r2, #1
+    orr     r3, r3, r3, lsl #16
+    mov     r3, r3, lsr #8
+    strh    r3, [r0], #2
+
+mcp16bs_aligned:
+    stmfd   sp!, {r4,lr}
+    mov     lr, #0xff
+    orr     lr, lr, lr, lsl #16
+
+    subs    r2, r2, #4
+    bmi     mcp16bs_fin4
+
+mcp16bs_loop:
+    ldmia   r1!, {r3,r12}
+    subs    r2, r2, #4
+    bswap   r3
+    bswap   r12
+    stmia   r0!, {r3,r12}
+    bpl     mcp16bs_loop
+
+mcp16bs_fin4:
+    tst     r2, #2
+    beq     mcp16bs_fin2
+    ldr     r3, [r1], #4
+    bswap   r3
+    str     r3, [r0], #4
+
+mcp16bs_fin2:
+    ldmfd   sp!, {r4,lr}
+    ands    r2, r2, #1
+    bxeq    lr
+
+mcp16bs_cant_align:
+    ldrh    r3, [r1], #2
+    subs    r2, r2, #1
+    orr     r3, r3, r3, lsl #16
+    mov     r3, r3, lsr #8
+    strh    r3, [r0], #2
+    bne     mcp16bs_cant_align
+    bx      lr
+
+    @ worst case
+mcp16bs_cant_align2:
+    ldrb    r3, [r1], #1
+    ldrb    r12,[r1], #1
+    subs    r2, r2, #1
+    mov     r3, r3, lsl #8
+    orr     r3, r3, r12
+    strh    r3, [r0], #2
+    bne     mcp16bs_cant_align2
+    bx      lr
+
+
+
+.global memcpy32 @ int *dest, int *src, int count
+
+memcpy32:
+    stmfd   sp!, {r4,lr}
+
+    subs    r2, r2, #4
+    bmi     mcp32_fin
+
+mcp32_loop:
+    ldmia   r1!, {r3,r4,r12,lr}
+    subs    r2, r2, #4
+    stmia   r0!, {r3,r4,r12,lr}
+    bpl     mcp32_loop
+
+mcp32_fin:
+    tst     r2, #3
+    ldmeqfd sp!, {r4,pc}
+    tst     r2, #1
+    ldrne   r3, [r1], #4
+    strne   r3, [r0], #4
+
+mcp32_no_unal1:
+    tst     r2, #2
+    ldmneia r1!, {r3,r12}
+    ldmfd   sp!, {r4,lr}
+    stmneia r0!, {r3,r12}
+    bx      lr
+
+
+
+.global memset32 @ int *dest, int c, int count
+
+memset32:
+    stmfd   sp!, {lr}
+
+    mov     r3, r1
+    subs    r2, r2, #4
+    bmi     mst32_fin
+
+    mov     r12,r1
+    mov     lr, r1
+
+mst32_loop:
+    subs    r2, r2, #4
+    stmia   r0!, {r1,r3,r12,lr}
+    bpl     mst32_loop
+
+mst32_fin:
+    tst     r2, #1
+    strne   r1, [r0], #4
+
+    tst     r2, #2
+    stmneia r0!, {r1,r3}
+
+    ldmfd   sp!, {lr}
+    bx      lr
+
+
+