Skip to content

Commit

Permalink
Thumb-2: Implement the unified arch/arm/lib functions
Browse files Browse the repository at this point in the history
This patch adds the ARM/Thumb-2 unified support for the arch/arm/lib/*
files.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
  • Loading branch information
Catalin Marinas committed Jul 24, 2009
1 parent 347c8b7 commit 8b59278
Show file tree
Hide file tree
Showing 20 changed files with 229 additions and 98 deletions.
73 changes: 73 additions & 0 deletions arch/arm/include/asm/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,76 @@
msr cpsr_c, #\mode
.endm
#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
7 changes: 5 additions & 2 deletions arch/arm/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/memory.h>
#include <asm/domain.h>
#include <asm/system.h>
#include <asm/unified.h>

#define VERIFY_READ 0
#define VERIFY_WRITE 1
Expand Down Expand Up @@ -365,8 +366,10 @@ do { \

#define __put_user_asm_dword(x,__pu_addr,err) \
__asm__ __volatile__( \
"1: strt " __reg_oper1 ", [%1], #4\n" \
"2: strt " __reg_oper0 ", [%1]\n" \
ARM( "1: strt " __reg_oper1 ", [%1], #4\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" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
Expand Down
4 changes: 3 additions & 1 deletion arch/arm/lib/ashldi3.S
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ ENTRY(__aeabi_llsl)
rsb ip, r2, #32
movmi ah, ah, lsl r2
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 pc, lr

Expand Down
4 changes: 3 additions & 1 deletion arch/arm/lib/ashrdi3.S
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ ENTRY(__aeabi_lasr)
rsb ip, r2, #32
movmi al, al, lsr r2
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 pc, lr

Expand Down
8 changes: 6 additions & 2 deletions arch/arm/lib/backtrace.S
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ ENDPROC(c_backtrace)
beq no_frame @ we have no stack frames

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

1: stmfd sp!, {pc} @ calculate offset of PC stored
Expand Down Expand Up @@ -126,7 +128,9 @@ ENDPROC(c_backtrace)
mov reg, #10
mov r7, #0
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
add r7, r7, #1
teq r7, #6
Expand Down
15 changes: 7 additions & 8 deletions arch/arm/lib/clear_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,20 @@ WEAK(__clear_user)
ands ip, r0, #3
beq 1f
cmp ip, #2
USER( strbt r2, [r0], #1)
USER( strlebt r2, [r0], #1)
USER( strltbt r2, [r0], #1)
strusr r2, r0, 1
strusr r2, r0, 1, le
strusr r2, r0, 1, lt
rsb ip, ip, #4
sub r1, r1, ip @ 7 6 5 4 3 2 1
1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
USER( strplt r2, [r0], #4)
USER( strplt r2, [r0], #4)
strusr r2, r0, 4, pl, rept=2
bpl 1b
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
USER( strnebt r2, [r0], #1)
USER( strnebt r2, [r0], #1)
strusr r2, r0, 1, ne, rept=2
tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
it ne @ explicit IT needed for the label
USER( strnebt r2, [r0])
mov r0, #0
ldmfd sp!, {r1, pc}
Expand Down
19 changes: 10 additions & 9 deletions arch/arm/lib/copy_from_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@
* 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
100: ldrt \reg, [\ptr], #4
.section __ex_table, "a"
.long 100b, \abort
.previous
ldrusr \reg, \ptr, 4, abort=\abort
.endm

.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
Expand All @@ -53,14 +57,11 @@
.endm

.macro ldr1b ptr reg cond=al abort
100: ldr\cond\()bt \reg, [\ptr], #1
.section __ex_table, "a"
.long 100b, \abort
.previous
ldrusr \reg, \ptr, 1, \cond, abort=\abort
.endm

.macro str1w ptr reg abort
str \reg, [\ptr], #4
W(str) \reg, [\ptr], #4
.endm

.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
Expand Down
24 changes: 22 additions & 2 deletions arch/arm/lib/copy_template.S
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@
*
* Restore registers with the values previously saved with the
* '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)
*/


Expand Down Expand Up @@ -99,9 +106,15 @@

5: ands ip, r2, #28
rsb ip, ip, #32
#if LDR1W_SHIFT > 0
lsl ip, ip, #LDR1W_SHIFT
#endif
addne pc, pc, ip @ C is always clear here
b 7f
6: nop
6:
.rept (1 << LDR1W_SHIFT)
W(nop)
.endr
ldr1w r1, r3, abort=20f
ldr1w r1, r4, abort=20f
ldr1w r1, r5, abort=20f
Expand All @@ -110,9 +123,16 @@
ldr1w r1, r8, 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
nop
nop
.rept (1 << STR1W_SHIFT)
W(nop)
.endr
str1w r0, r3, abort=20f
str1w r0, r4, abort=20f
str1w r0, r5, abort=20f
Expand Down
19 changes: 10 additions & 9 deletions arch/arm/lib/copy_to_user.S
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@
* 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
ldr \reg, [\ptr], #4
W(ldr) \reg, [\ptr], #4
.endm

.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
Expand All @@ -50,10 +57,7 @@
.endm

.macro str1w ptr reg abort
100: strt \reg, [\ptr], #4
.section __ex_table, "a"
.long 100b, \abort
.previous
strusr \reg, \ptr, 4, abort=\abort
.endm

.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
Expand All @@ -68,10 +72,7 @@
.endm

.macro str1b ptr reg cond=al abort
100: str\cond\()bt \reg, [\ptr], #1
.section __ex_table, "a"
.long 100b, \abort
.previous
strusr \reg, \ptr, 1, \cond, abort=\abort
.endm

.macro enter reg1 reg2
Expand Down
48 changes: 13 additions & 35 deletions arch/arm/lib/csumpartialcopyuser.S
Original file line number Diff line number Diff line change
Expand Up @@ -26,50 +26,28 @@
.endm

.macro load1b, reg1
9999: ldrbt \reg1, [r0], $1
.section __ex_table, "a"
.align 3
.long 9999b, 6001f
.previous
ldrusr \reg1, r0, 1
.endm

.macro load2b, reg1, reg2
9999: ldrbt \reg1, [r0], $1
9998: ldrbt \reg2, [r0], $1
.section __ex_table, "a"
.long 9999b, 6001f
.long 9998b, 6001f
.previous
ldrusr \reg1, r0, 1
ldrusr \reg2, r0, 1
.endm

.macro load1l, reg1
9999: ldrt \reg1, [r0], $4
.section __ex_table, "a"
.align 3
.long 9999b, 6001f
.previous
ldrusr \reg1, r0, 4
.endm

.macro load2l, reg1, reg2
9999: ldrt \reg1, [r0], $4
9998: ldrt \reg2, [r0], $4
.section __ex_table, "a"
.long 9999b, 6001f
.long 9998b, 6001f
.previous
ldrusr \reg1, r0, 4
ldrusr \reg2, r0, 4
.endm

.macro load4l, reg1, reg2, reg3, reg4
9999: ldrt \reg1, [r0], $4
9998: ldrt \reg2, [r0], $4
9997: ldrt \reg3, [r0], $4
9996: ldrt \reg4, [r0], $4
.section __ex_table, "a"
.long 9999b, 6001f
.long 9998b, 6001f
.long 9997b, 6001f
.long 9996b, 6001f
.previous
ldrusr \reg1, r0, 4
ldrusr \reg2, r0, 4
ldrusr \reg3, r0, 4
ldrusr \reg4, r0, 4
.endm

/*
Expand All @@ -92,14 +70,14 @@
*/
.section .fixup,"ax"
.align 4
6001: mov r4, #-EFAULT
9001: mov r4, #-EFAULT
ldr r5, [fp, #4] @ *err_ptr
str r4, [r5]
ldmia sp, {r1, r2} @ retrieve dst, len
add r2, r2, r1
mov r0, #0 @ zero the buffer
6002: teq r2, r1
9002: teq r2, r1
strneb r0, [r1], #1
bne 6002b
bne 9002b
load_regs
.previous
4 changes: 3 additions & 1 deletion arch/arm/lib/div64.S
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ ENTRY(__do_div64)
mov yh, xh, lsr ip
mov yl, xl, lsr ip
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, xh, lsr ip
mov pc, lr
Expand Down
Loading

0 comments on commit 8b59278

Please sign in to comment.