Commit 8b592783 authored by Catalin Marinas's avatar Catalin Marinas

Thumb-2: Implement the unified arch/arm/lib functions

This patch adds the ARM/Thumb-2 unified support for the arch/arm/lib/*
files.
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>

parent 347c8b70
...@@ -138,3 +138,76 @@ ...@@ -138,3 +138,76 @@
msr cpsr_c, #\mode msr cpsr_c, #\mode
.endm .endm
#endif #endif
/*
* STRT/LDRT access macros with ARM and Thumb-2 variants
*/
#ifdef CONFIG_THUMB2_KERNEL
.macro usraccoff, instr, reg, ptr, inc, off, cond, abort
9999:
.if \inc == 1
\instr\cond\()bt \reg, [\ptr, #\off]
.elseif \inc == 4
\instr\cond\()t \reg, [\ptr, #\off]
.else
.error "Unsupported inc macro argument"
.endif
.section __ex_table,"a"
.align 3
.long 9999b, \abort
.previous
.endm
.macro usracc, instr, reg, ptr, inc, cond, rept, abort
@ explicit IT instruction needed because of the label
@ introduced by the USER macro
.ifnc \cond,al
.if \rept == 1
itt \cond
.elseif \rept == 2
ittt \cond
.else
.error "Unsupported rept macro argument"
.endif
.endif
@ Slightly optimised to avoid incrementing the pointer twice
usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
.if \rept == 2
usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort
.endif
add\cond \ptr, #\rept * \inc
.endm
#else /* !CONFIG_THUMB2_KERNEL */
.macro usracc, instr, reg, ptr, inc, cond, rept, abort
.rept \rept
9999:
.if \inc == 1
\instr\cond\()bt \reg, [\ptr], #\inc
.elseif \inc == 4
\instr\cond\()t \reg, [\ptr], #\inc
.else
.error "Unsupported inc macro argument"
.endif
.section __ex_table,"a"
.align 3
.long 9999b, \abort
.previous
.endr
.endm
#endif /* CONFIG_THUMB2_KERNEL */
.macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
usracc str, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
.macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/domain.h> #include <asm/domain.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/unified.h>
#define VERIFY_READ 0 #define VERIFY_READ 0
#define VERIFY_WRITE 1 #define VERIFY_WRITE 1
...@@ -365,8 +366,10 @@ do { \ ...@@ -365,8 +366,10 @@ do { \
#define __put_user_asm_dword(x,__pu_addr,err) \ #define __put_user_asm_dword(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: strt " __reg_oper1 ", [%1], #4\n" \ ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \
"2: strt " __reg_oper0 ", [%1]\n" \ ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \
THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \
THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \
"3:\n" \ "3:\n" \
" .section .fixup,\"ax\"\n" \ " .section .fixup,\"ax\"\n" \
" .align 2\n" \ " .align 2\n" \
......
...@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsl) ...@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsl)
rsb ip, r2, #32 rsb ip, r2, #32
movmi ah, ah, lsl r2 movmi ah, ah, lsl r2
movpl ah, al, lsl r3 movpl ah, al, lsl r3
orrmi ah, ah, al, lsr ip ARM( orrmi ah, ah, al, lsr ip )
THUMB( lsrmi r3, al, ip )
THUMB( orrmi ah, ah, r3 )
mov al, al, lsl r2 mov al, al, lsl r2
mov pc, lr mov pc, lr
......
...@@ -43,7 +43,9 @@ ENTRY(__aeabi_lasr) ...@@ -43,7 +43,9 @@ ENTRY(__aeabi_lasr)
rsb ip, r2, #32 rsb ip, r2, #32
movmi al, al, lsr r2 movmi al, al, lsr r2
movpl al, ah, asr r3 movpl al, ah, asr r3
orrmi al, al, ah, lsl ip ARM( orrmi al, al, ah, lsl ip )
THUMB( lslmi r3, ah, ip )
THUMB( orrmi al, al, r3 )
mov ah, ah, asr r2 mov ah, ah, asr r2
mov pc, lr mov pc, lr
......
...@@ -38,7 +38,9 @@ ENDPROC(c_backtrace) ...@@ -38,7 +38,9 @@ ENDPROC(c_backtrace)
beq no_frame @ we have no stack frames beq no_frame @ we have no stack frames
tst r1, #0x10 @ 26 or 32-bit mode? tst r1, #0x10 @ 26 or 32-bit mode?
moveq mask, #0xfc000003 @ mask for 26-bit ARM( moveq mask, #0xfc000003 )
THUMB( moveq mask, #0xfc000000 )
THUMB( orreq mask, #0x03 )
movne mask, #0 @ mask for 32-bit movne mask, #0 @ mask for 32-bit
1: stmfd sp!, {pc} @ calculate offset of PC stored 1: stmfd sp!, {pc} @ calculate offset of PC stored
...@@ -126,7 +128,9 @@ ENDPROC(c_backtrace) ...@@ -126,7 +128,9 @@ ENDPROC(c_backtrace)
mov reg, #10 mov reg, #10
mov r7, #0 mov r7, #0
1: mov r3, #1 1: mov r3, #1
tst instr, r3, lsl reg ARM( tst instr, r3, lsl reg )
THUMB( lsl r3, reg )
THUMB( tst instr, r3 )
beq 2f beq 2f
add r7, r7, #1 add r7, r7, #1
teq r7, #6 teq r7, #6
......
...@@ -27,21 +27,20 @@ WEAK(__clear_user) ...@@ -27,21 +27,20 @@ WEAK(__clear_user)
ands ip, r0, #3 ands ip, r0, #3
beq 1f beq 1f
cmp ip, #2 cmp ip, #2
USER( strbt r2, [r0], #1) strusr r2, r0, 1
USER( strlebt r2, [r0], #1) strusr r2, r0, 1, le
USER( strltbt r2, [r0], #1) strusr r2, r0, 1, lt
rsb ip, ip, #4 rsb ip, ip, #4
sub r1, r1, ip @ 7 6 5 4 3 2 1 sub r1, r1, ip @ 7 6 5 4 3 2 1
1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
USER( strplt r2, [r0], #4) strusr r2, r0, 4, pl, rept=2
USER( strplt r2, [r0], #4)
bpl 1b bpl 1b
adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
USER( strplt r2, [r0], #4) strusr r2, r0, 4, pl
2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x 2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
USER( strnebt r2, [r0], #1) strusr r2, r0, 1, ne, rept=2
USER( strnebt r2, [r0], #1)
tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
it ne @ explicit IT needed for the label
USER( strnebt r2, [r0]) USER( strnebt r2, [r0])
mov r0, #0 mov r0, #0
ldmfd sp!, {r1, pc} ldmfd sp!, {r1, pc}
......
...@@ -33,11 +33,15 @@ ...@@ -33,11 +33,15 @@
* Number of bytes NOT copied. * Number of bytes NOT copied.
*/ */
#ifndef CONFIG_THUMB2_KERNEL
#define LDR1W_SHIFT 0
#else
#define LDR1W_SHIFT 1
#endif
#define STR1W_SHIFT 0
.macro ldr1w ptr reg abort .macro ldr1w ptr reg abort
100: ldrt \reg, [\ptr], #4 ldrusr \reg, \ptr, 4, abort=\abort
.section __ex_table, "a"
.long 100b, \abort
.previous
.endm .endm
.macro ldr4w ptr reg1 reg2 reg3 reg4 abort .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
...@@ -53,14 +57,11 @@ ...@@ -53,14 +57,11 @@
.endm .endm
.macro ldr1b ptr reg cond=al abort .macro ldr1b ptr reg cond=al abort
100: ldr\cond\()bt \reg, [\ptr], #1 ldrusr \reg, \ptr, 1, \cond, abort=\abort
.section __ex_table, "a"
.long 100b, \abort
.previous
.endm .endm
.macro str1w ptr reg abort .macro str1w ptr reg abort
str \reg, [\ptr], #4 W(str) \reg, [\ptr], #4
.endm .endm
.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
......
...@@ -57,6 +57,13 @@ ...@@ -57,6 +57,13 @@
* *
* Restore registers with the values previously saved with the * Restore registers with the values previously saved with the
* 'preserv' macro. Called upon code termination. * 'preserv' macro. Called upon code termination.
*
* LDR1W_SHIFT
* STR1W_SHIFT
*
* Correction to be applied to the "ip" register when branching into
* the ldr1w or str1w instructions (some of these macros may expand to
* than one 32bit instruction in Thumb-2)
*/ */
...@@ -99,9 +106,15 @@ ...@@ -99,9 +106,15 @@
5: ands ip, r2, #28 5: ands ip, r2, #28
rsb ip, ip, #32 rsb ip, ip, #32
#if LDR1W_SHIFT > 0
lsl ip, ip, #LDR1W_SHIFT
#endif
addne pc, pc, ip @ C is always clear here addne pc, pc, ip @ C is always clear here
b 7f b 7f
6: nop 6:
.rept (1 << LDR1W_SHIFT)
W(nop)
.endr
ldr1w r1, r3, abort=20f ldr1w r1, r3, abort=20f
ldr1w r1, r4, abort=20f ldr1w r1, r4, abort=20f
ldr1w r1, r5, abort=20f ldr1w r1, r5, abort=20f
...@@ -110,9 +123,16 @@ ...@@ -110,9 +123,16 @@
ldr1w r1, r8, abort=20f ldr1w r1, r8, abort=20f
ldr1w r1, lr, abort=20f ldr1w r1, lr, abort=20f
#if LDR1W_SHIFT < STR1W_SHIFT
lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
#elif LDR1W_SHIFT > STR1W_SHIFT
lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
#endif
add pc, pc, ip add pc, pc, ip
nop nop
nop .rept (1 << STR1W_SHIFT)
W(nop)
.endr
str1w r0, r3, abort=20f str1w r0, r3, abort=20f
str1w r0, r4, abort=20f str1w r0, r4, abort=20f
str1w r0, r5, abort=20f str1w r0, r5, abort=20f
......
...@@ -33,8 +33,15 @@ ...@@ -33,8 +33,15 @@
* Number of bytes NOT copied. * Number of bytes NOT copied.
*/ */
#define LDR1W_SHIFT 0
#ifndef CONFIG_THUMB2_KERNEL
#define STR1W_SHIFT 0
#else
#define STR1W_SHIFT 1
#endif
.macro ldr1w ptr reg abort .macro ldr1w ptr reg abort
ldr \reg, [\ptr], #4 W(ldr) \reg, [\ptr], #4
.endm .endm
.macro ldr4w ptr reg1 reg2 reg3 reg4 abort .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
...@@ -50,10 +57,7 @@ ...@@ -50,10 +57,7 @@
.endm .endm
.macro str1w ptr reg abort .macro str1w ptr reg abort
100: strt \reg, [\ptr], #4 strusr \reg, \ptr, 4, abort=\abort
.section __ex_table, "a"
.long 100b, \abort
.previous
.endm .endm
.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
...@@ -68,10 +72,7 @@ ...@@ -68,10 +72,7 @@
.endm .endm
.macro str1b ptr reg cond=al abort .macro str1b ptr reg cond=al abort
100: str\cond\()bt \reg, [\ptr], #1 strusr \reg, \ptr, 1, \cond, abort=\abort
.section __ex_table, "a"
.long 100b, \abort
.previous
.endm .endm
.macro enter reg1 reg2 .macro enter reg1 reg2
......
...@@ -26,50 +26,28 @@ ...@@ -26,50 +26,28 @@
.endm .endm
.macro load1b, reg1 .macro load1b, reg1
9999: ldrbt \reg1, [r0], $1 ldrusr \reg1, r0, 1
.section __ex_table, "a"
.align 3
.long 9999b, 6001f
.previous
.endm .endm
.macro load2b, reg1, reg2 .macro load2b, reg1, reg2
9999: ldrbt \reg1, [r0], $1 ldrusr \reg1, r0, 1
9998: ldrbt \reg2, [r0], $1 ldrusr \reg2, r0, 1
.section __ex_table, "a"
.long 9999b, 6001f
.long 9998b, 6001f
.previous
.endm .endm
.macro load1l, reg1 .macro load1l, reg1
9999: ldrt \reg1, [r0], $4 ldrusr \reg1, r0, 4
.section __ex_table, "a"
.align 3
.long 9999b, 6001f
.previous
.endm .endm
.macro load2l, reg1, reg2 .macro load2l, reg1, reg2
9999: ldrt \reg1, [r0], $4 ldrusr \reg1, r0, 4
9998: ldrt \reg2, [r0], $4 ldrusr \reg2, r0, 4
.section __ex_table, "a"
.long 9999b, 6001f
.long 9998b, 6001f
.previous
.endm .endm
.macro load4l, reg1, reg2, reg3, reg4 .macro load4l, reg1, reg2, reg3, reg4
9999: ldrt \reg1, [r0], $4 ldrusr \reg1, r0, 4
9998: ldrt \reg2, [r0], $4 ldrusr \reg2, r0, 4
9997: ldrt \reg3, [r0], $4 ldrusr \reg3, r0, 4
9996: ldrt \reg4, [r0], $4 ldrusr \reg4, r0, 4
.section __ex_table, "a"
.long 9999b, 6001f
.long 9998b, 6001f
.long 9997b, 6001f
.long 9996b, 6001f
.previous
.endm .endm
/* /*
...@@ -92,14 +70,14 @@ ...@@ -92,14 +70,14 @@
*/ */
.section .fixup,"ax" .section .fixup,"ax"
.align 4 .align 4
6001: mov r4, #-EFAULT 9001: mov r4, #-EFAULT
ldr r5, [fp, #4] @ *err_ptr ldr r5, [fp, #4] @ *err_ptr
str r4, [r5] str r4, [r5]
ldmia sp, {r1, r2} @ retrieve dst, len ldmia sp, {r1, r2} @ retrieve dst, len
add r2, r2, r1 add r2, r2, r1
mov r0, #0 @ zero the buffer mov r0, #0 @ zero the buffer
6002: teq r2, r1 9002: teq r2, r1
strneb r0, [r1], #1 strneb r0, [r1], #1
bne 6002b bne 9002b
load_regs load_regs
.previous .previous
...@@ -177,7 +177,9 @@ ENTRY(__do_div64) ...@@ -177,7 +177,9 @@ ENTRY(__do_div64)
mov yh, xh, lsr ip mov yh, xh, lsr ip
mov yl, xl, lsr ip mov yl, xl, lsr ip
rsb ip, ip, #32 rsb ip, ip, #32
orr yl, yl, xh, lsl ip ARM( orr yl, yl, xh, lsl ip )
THUMB( lsl xh, xh, ip )
THUMB( orr yl, yl, xh )
mov xh, xl, lsl ip mov xh, xl, lsl ip
mov xh, xh, lsr ip mov xh, xh, lsr ip
mov pc, lr mov pc, lr
......
...@@ -25,7 +25,10 @@ ENTRY(_find_first_zero_bit_le) ...@@ -25,7 +25,10 @@ ENTRY(_find_first_zero_bit_le)
teq r1, #0 teq r1, #0
beq 3f beq 3f
mov r2, #0 mov r2, #0
1: ldrb r3, [r0, r2, lsr #3] 1:
ARM( ldrb r3, [r0, r2, lsr #3] )
THUMB( lsr r3, r2, #3 )
THUMB( ldrb r3, [r0, r3] )
eors r3, r3, #0xff @ invert bits eors r3, r3, #0xff @ invert bits
bne .L_found @ any now set - found zero bit bne .L_found @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer add r2, r2, #8 @ next bit pointer
...@@ -44,7 +47,9 @@ ENTRY(_find_next_zero_bit_le) ...@@ -44,7 +47,9 @@ ENTRY(_find_next_zero_bit_le)
beq 3b beq 3b
ands ip, r2, #7 ands ip, r2, #7
beq 1b @ If new byte, goto old routine beq 1b @ If new byte, goto old routine
ldrb r3, [r0, r2, lsr #3] ARM( ldrb r3, [r0, r2, lsr #3] )
THUMB( lsr r3, r2, #3 )
THUMB( ldrb r3, [r0, r3] )
eor r3, r3, #0xff @ now looking for a 1 bit eor r3, r3, #0xff @ now looking for a 1 bit
movs r3, r3, lsr ip @ shift off unused bits movs r3, r3, lsr ip @ shift off unused bits
bne .L_found bne .L_found
...@@ -61,7 +66,10 @@ ENTRY(_find_first_bit_le) ...@@ -61,7 +66,10 @@ ENTRY(_find_first_bit_le)
teq r1, #0 teq r1, #0
beq 3f beq 3f
mov r2, #0 mov r2, #0
1: ldrb r3, [r0, r2, lsr #3] 1:
ARM( ldrb r3, [r0, r2, lsr #3] )
THUMB( lsr r3, r2, #3 )
THUMB( ldrb r3, [r0, r3] )
movs r3, r3 movs r3, r3
bne .L_found @ any now set - found zero bit bne .L_found @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer add r2, r2, #8 @ next bit pointer
...@@ -80,7 +88,9 @@ ENTRY(_find_next_bit_le) ...@@ -80,7 +88,9 @@ ENTRY(_find_next_bit_le)
beq 3b beq 3b
ands ip, r2, #7 ands ip, r2, #7
beq 1b @ If new byte, goto old routine beq 1b @ If new byte, goto old routine
ldrb r3, [r0, r2, lsr #3] ARM( ldrb r3, [r0, r2, lsr #3] )
THUMB( lsr r3, r2, #3 )
THUMB( ldrb r3, [r0, r3] )
movs r3, r3, lsr ip @ shift off unused bits movs r3, r3, lsr ip @ shift off unused bits
bne .L_found bne .L_found
orr r2, r2, #7 @ if zero, then no bits here orr r2, r2, #7 @ if zero, then no bits here
...@@ -95,7 +105,9 @@ ENTRY(_find_first_zero_bit_be) ...@@ -95,7 +105,9 @@ ENTRY(_find_first_zero_bit_be)
beq 3f beq 3f
mov r2, #0 mov r2, #0
1: eor r3, r2, #0x18 @ big endian byte ordering 1: eor r3, r2, #0x18 @ big endian byte ordering
ldrb r3, [r0, r3, lsr #3] ARM( ldrb r3, [r0, r3, lsr #3] )
THUMB( lsr r3, #3 )
THUMB( ldrb r3, [r0, r3] )
eors r3, r3, #0xff @ invert bits eors r3, r3, #0xff @ invert bits
bne .L_found @ any now set - found zero bit bne .L_found @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer add r2, r2, #8 @ next bit pointer
...@@ -111,7 +123,9 @@ ENTRY(_find_next_zero_bit_be) ...@@ -111,7 +123,9 @@ ENTRY(_find_next_zero_bit_be)
ands ip, r2, #7 ands ip, r2, #7
beq 1b @ If new byte, goto old routine beq 1b @ If new byte, goto old routine
eor r3, r2, #0x18 @ big endian byte ordering eor r3, r2, #0x18 @ big endian byte ordering
ldrb r3, [r0, r3, lsr #3] ARM( ldrb r3, [r0, r3, lsr #3] )
THUMB( lsr r3, #3 )
THUMB( ldrb r3, [r0, r3] )
eor r3, r3, #0xff @ now looking for a 1 bit eor r3, r3, #0xff @ now looking for a 1 bit
movs r3, r3, lsr ip @ shift off unused bits movs r3, r3, lsr ip @ shift off unused bits
bne .L_found bne .L_found
...@@ -125,7 +139,9 @@ ENTRY(_find_first_bit_be) ...@@ -125,7 +139,9 @@ ENTRY(_find_first_bit_be)
beq 3f beq 3f
mov r2, #0 mov r2, #0
1: eor r3, r2, #0x18 @ big endian byte ordering 1: eor r3, r2, #0x18 @ big endian byte ordering
ldrb r3, [r0, r3, lsr #3] ARM( ldrb r3, [r0, r3, lsr #3] )
THUMB( lsr r3, #3 )
THUMB( ldrb r3, [r0, r3] )
movs r3, r3 movs r3, r3
bne .L_found @ any now set - found zero bit bne .L_found @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer add r2, r2, #8 @ next bit pointer
...@@ -141,7 +157,9 @@ ENTRY(_find_next_bit_be) ...@@ -141,7 +157,9 @@ ENTRY(_find_next_bit_be)
ands ip, r2, #7 ands ip, r2, #7
beq 1b @ If new byte, goto old routine beq 1b @ If new byte, goto old routine
eor r3, r2, #0x18 @ big endian byte ordering eor r3, r2, #0x18 @ big endian byte ordering
ldrb r3, [r0, r3, lsr #3] ARM( ldrb r3, [r0, r3, lsr #3] )
THUMB( lsr r3, #3 )
THUMB( ldrb r3, [r0, r3] )
movs r3, r3, lsr ip @ shift off unused bits movs r3, r3, lsr ip @ shift off unused bits
bne .L_found bne .L_found
orr r2, r2, #7 @ if zero, then no bits here orr r2, r2, #7 @ if zero, then no bits here
......
...@@ -36,8 +36,13 @@ ENTRY(__get_user_1) ...@@ -36,8 +36,13 @@ ENTRY(__get_user_1)
ENDPROC(__get_user_1) ENDPROC(__get_user_1)
ENTRY(__get_user_2) ENTRY(__get_user_2)
#ifdef CONFIG_THUMB2_KERNEL
2: ldrbt r2, [r0]
3: ldrbt r3, [r0, #1]
#else
2: ldrbt r2, [r0], #1 2: ldrbt r2, [r0], #1
3: ldrbt r3, [r0] 3: ldrbt r3, [r0]
#endif
#ifndef __ARMEB__ #ifndef __ARMEB__
orr r2, r2, r3, lsl #8 orr r2, r2, r3, lsl #8
#else #else
......
...@@ -75,7 +75,10 @@ ENTRY(__raw_writesw) ...@@ -75,7 +75,10 @@ ENTRY(__raw_writesw)
#endif #endif
.Loutsw_noalign: .Loutsw_noalign:
ldr r3, [r1, -r3]! ARM( ldr r3, [r1, -r3]! )
THUMB( rsb r3, r3, #0 )
THUMB( ldr r3, [r1, r3] )
THUMB( sub r1, r3 )
subcs r2, r2, #1 subcs r2, r2, #1
bcs 2f bcs 2f
subs r2, r2, #2 subs r2, r2, #2
......
...@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsr) ...@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsr)
rsb ip, r2, #32 rsb ip, r2, #32
movmi al, al, lsr r2 movmi al, al, lsr r2
movpl al, ah, lsr r3 movpl al, ah, lsr r3
orrmi al, al, ah, lsl ip ARM( orrmi al, al, ah, lsl ip )
THUMB( lslmi r3, ah, ip )
THUMB( orrmi al, al, r3 )
mov ah, ah, lsr r2 mov ah, ah, lsr r2
mov pc, lr mov pc, lr
......
...@@ -13,8 +13,11 @@ ...@@ -13,8 +13,11 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#define LDR1W_SHIFT 0
#define STR1W_SHIFT 0
.macro ldr1w ptr reg abort .macro ldr1w ptr reg abort
ldr \reg, [\ptr], #4 W(ldr) \reg, [\ptr], #4
.endm .endm
.macro ldr4w ptr reg1 reg2 reg3 reg4 abort .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
...@@ -30,7 +33,7 @@ ...@@ -30,7 +33,7 @@
.endm .endm
.macro str1w ptr reg abort .macro str1w ptr reg abort
str \reg, [\ptr], #4 W(str) \reg, [\ptr], #4
.endm .endm
.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
......
...@@ -75,24 +75,24 @@ ENTRY(memmove) ...@@ -75,24 +75,24 @@ ENTRY(memmove)
addne pc, pc, ip @ C is always clear here addne pc, pc, ip @ C is always clear here
b 7f b 7f
6: nop 6: nop
ldr r3, [r1, #-4]! W(ldr) r3, [r1, #-4]!
ldr r4, [r1, #-4]! W(ldr) r4, [r1, #-4]!
ldr r5, [r1, #-4]! W(ldr) r5, [r1, #-4]!
ldr r6, [r1, #-4]! W(ldr) r6, [r1, #-4]!
ldr r7, [r1, #-4]! W(ldr) r7, [r1, #-4]!
ldr r8, [r1, #-4]! W(ldr) r8, [r1, #-4]!
ldr lr, [r1, #-4]! W(ldr) lr, [r1, #-4]!
add pc, pc, ip add pc, pc, ip
nop nop
nop nop
str r3, [r0, #-4]! W(str) r3, [r0, #-4]!
str r4, [r0, #-4]! W(str) r4, [r0, #-4]!
str r5, [r0, #-4]! W(str) r5, [r0, #-4]!
str r6, [r0, #-4]! W(str) r6, [r0, #-4]!
str r7, [r0, #-4]! W(str) r7, [r0, #-4]!
str r8, [r0, #-4]! W(str) r8, [r0, #-4]!
str lr, [r0, #-4]! W(str) lr, [r0, #-4]!
CALGN( bcs 2b ) CALGN( bcs 2b )
......
...@@ -37,6 +37,15 @@ ENDPROC(__put_user_1) ...@@ -37,6 +37,15 @@ ENDPROC(__put_user_1)
ENTRY(__put_user_2) ENTRY(__put_user_2)
mov ip, r2, lsr #8 mov ip, r2, lsr #8
#ifdef CONFIG_THUMB2_KERNEL
#ifndef __ARMEB__
2: strbt r2, [r0]
3: strbt ip, [r0, #1]
#else
2: strbt ip, [r0]
3: strbt r2, [r0, #1]
#endif
#else /* !CONFIG_THUMB2_KERNEL */
#ifndef __ARMEB__ #ifndef __ARMEB__
2: strbt r2, [r0], #1 2: strbt r2, [r0], #1
3: strbt ip, [r0] 3: strbt ip, [r0]
...@@ -44,6 +53,7 @@ ENTRY(__put_user_2) ...@@ -44,6 +53,7 @@ ENTRY(__put_user_2)
2: strbt ip, [r0], #1 2: strbt ip, [r0], #1
3: strbt r2, [r0] 3: strbt r2, [r0]
#endif #endif
#endif /* CONFIG_THUMB2_KERNEL */
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
ENDPROC(__put_user_2) ENDPROC(__put_user_2)
...@@ -55,8 +65,13 @@ ENTRY(__put_user_4) ...@@ -55,8 +65,13 @@ ENTRY(__put_user_4)
ENDPROC(__put_user_4) ENDPROC(__put_user_4)
ENTRY(__put_user_8) ENTRY(__put_user_8)
#ifdef CONFIG_THUMB2_KERNEL
5: strt r2, [r0]
6: strt r3, [r0, #4]
#else
5: strt r2, [r0], #4 5: strt r2, [r0], #4
6: strt r3, [r0] 6: strt r3, [r0]
#endif
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
ENDPROC(__put_user_8) ENDPROC(__put_user_8)
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
ENTRY(__strncpy_from_user) ENTRY(__strncpy_from_user)
mov ip, r1 mov ip, r1
1: subs r2, r2, #1 1: subs r2, r2, #1
USER( ldrplbt r3, [r1], #1) ldrusr r3, r1, 1, pl
bmi 2f bmi 2f
strb r3, [r0], #1 strb r3, [r0], #1
teq r3, #0 teq r3, #0
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
ENTRY(__strnlen_user) ENTRY(__strnlen_user)
mov r2, r0 mov r2, r0
1: 1:
USER( ldrbt r3, [r0], #1) ldrusr r3, r0, 1
teq r3, #0 teq r3, #0
beq 2f beq 2f
subs r1, r1, #1 subs r1, r1, #1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment