This commit is contained in:
2015-11-15 18:18:42 +00:00
parent 9ac343fc45
commit 72be7b0c2f
580 changed files with 356252 additions and 6 deletions
+33
View File
@@ -0,0 +1,33 @@
.macro bitop, instr
and r2, r0, #7
mov r3, #1
mov r3, r3, lsl r2
save_and_disable_irqs ip
ldrb r2, [r1, r0, lsr #3]
\instr r2, r2, r3
strb r2, [r1, r0, lsr #3]
restore_irqs ip
mov pc, lr
.endm
/**
* testop - implement a test_and_xxx_bit operation.
* @instr: operational instruction
* @store: store instruction
*
* Note: we can trivially conditionalise the store instruction
* to avoid dirting the data cache.
*/
.macro testop, instr, store
add r1, r1, r0, lsr #3
and r3, r0, #7
mov r0, #1
save_and_disable_irqs ip
ldrb r2, [r1]
tst r2, r0, lsl r3
\instr r2, r2, r0, lsl r3
\store r2, [r1]
restore_irqs ip
moveq r0, #0
mov pc, lr
.endm
+21
View File
@@ -0,0 +1,21 @@
/*
* linux/arch/arm/lib/changebit.S
*
* Copyright (C) 1995-1996 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
#include "bitops.h"
.text
/* Purpose : Function to change a bit
* Prototype: int change_bit(int bit, void *addr)
*/
ENTRY(_change_bit_be)
eor r0, r0, #0x18 @ big endian byte ordering
ENTRY(_change_bit_le)
bitop eor
+169
View File
@@ -0,0 +1,169 @@
1 # 1 "lib/changebit.S"
1 /*
0
0
2 * linux/arch/arm/lib/changebit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
11 #include <asm/assembler.h>
1 /*
2 * linux/include/asm-arm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16 #ifndef __ASSEMBLY__
17 #error "Only include this from assembly code"
18 #endif
19
20 #include <asm/ptrace.h>
1 /*
21
22 #define pull lsl
23 #define push lsr
24 #define get_byte_0 lsr #24
25 #define get_byte_1 lsr #16
26 #define get_byte_2 lsr #8
27 #define get_byte_3 lsl #0
28 #define put_byte_0 lsl #24
29 #define put_byte_1 lsl #16
30 #define put_byte_2 lsl #8
31 #define put_byte_3 lsl #0
32
33 #define PLD(code...)
34
35 #define MODE_USR USR_MODE
36 #define MODE_FIQ FIQ_MODE
37 #define MODE_IRQ IRQ_MODE
38 #define MODE_SVC SVC_MODE
39
40 #define DEFAULT_FIQ MODE_FIQ
41
42 /*
43 * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
44 */
45 #ifdef __STDC__
46 #define LOADREGS(cond, base, reglist...)\
47 ldm##cond base,reglist
48 #else
49 #define LOADREGS(cond, base, reglist...)\
50 ldm/**/cond base,reglist
51 #endif
52
53 /*
54 * Build a return instruction for this processor type.
55 */
56 #define RETINSTR(instr, regs...)\
57 instr regs
58
59 /*
60 * Enable and disable interrupts
61 */
62 .macro disable_irq
63 msr cpsr_c, #PSR_I_BIT | SVC_MODE
64 .endm
65
66 .macro enable_irq
67 msr cpsr_c, #SVC_MODE
68 .endm
69
70 /*
71 * Save the current IRQ state and disable IRQs. Note that this macro
72 * assumes FIQs are enabled, and that the processor is in SVC mode.
73 */
74 .macro save_and_disable_irqs, oldcpsr
75 mrs \oldcpsr, cpsr
76 disable_irq
77 .endm
78
79 /*
80 * Restore interrupt state previously stored in a register. We don't
81 * guarantee that this will preserve the flags.
82 */
83 .macro restore_irqs, oldcpsr
84 msr cpsr_c, \oldcpsr
85 .endm
86
87 /*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we do. On 32-bit
90 * architecture, we can safely ignore this requirement.
91 */
92 .macro save_lr
93 .endm
94
95 .macro restore_pc
96 mov pc, lr
97 .endm
98 ...
12 #include "bitops.h"
1 .macro bitop, instr
2 and r2, r0, #7
3 mov r3, #1
4 mov r3, r3, lsl r2
5 save_and_disable_irqs ip
6 ldrb r2, [r1, r0, lsr #3]
7 \instr r2, r2, r3
8 strb r2, [r1, r0, lsr #3]
9 restore_irqs ip
10 mov pc, lr
11 .endm
12
13 /**
14 * testop - implement a test_and_xxx_bit operation.
15 * @instr: operational instruction
16 * @store: store instruction
17 *
18 * Note: we can trivially conditionalise the store instruction
19 * to avoid dirting the data cache.
20 */
21 .macro testop, instr, store
22 add r1, r1, r0, lsr #3
23 and r3, r0, #7
24 mov r0, #1
25 save_and_disable_irqs ip
26 ldrb r2, [r1]
27 tst r2, r0, lsl r3
28 \instr r2, r2, r0, lsl r3
29 \store r2, [r1]
30 restore_irqs ip
31 moveq r0, #0
32 mov pc, lr
33 .endm
34 ...
13 .text
14
15 /* Purpose : Function to change a bit
16 * Prototype: int change_bit(int bit, void *addr)
17 */
18 ENTRY(_change_bit_be)
19 0000 180020E2 eor r0, r0, #0x18 @ big endian byte ordering
20 ENTRY(_change_bit_le)
21 0004 072000E2 bitop eor
21 0130A0E3
21 1332A0E1
21 00C00FE1
21 93F021E3
DEFINED SYMBOLS
lib/changebit.S:18 .text:00000000 _change_bit_be
lib/changebit.S:18 .text:00000000 $a
lib/changebit.S:20 .text:00000004 _change_bit_le
.debug_aranges:0000000c $d
NO UNDEFINED SYMBOLS
+22
View File
@@ -0,0 +1,22 @@
/*
* linux/arch/arm/lib/clearbit.S
*
* Copyright (C) 1995-1996 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
#include "bitops.h"
.text
/*
* Purpose : Function to clear a bit
* Prototype: int clear_bit(int bit, void *addr)
*/
ENTRY(_clear_bit_be)
eor r0, r0, #0x18 @ big endian byte ordering
ENTRY(_clear_bit_le)
bitop bic
+170
View File
@@ -0,0 +1,170 @@
1 # 1 "lib/clearbit.S"
1 /*
0
0
2 * linux/arch/arm/lib/clearbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
11 #include <asm/assembler.h>
1 /*
2 * linux/include/asm-arm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16 #ifndef __ASSEMBLY__
17 #error "Only include this from assembly code"
18 #endif
19
20 #include <asm/ptrace.h>
1 /*
21
22 #define pull lsl
23 #define push lsr
24 #define get_byte_0 lsr #24
25 #define get_byte_1 lsr #16
26 #define get_byte_2 lsr #8
27 #define get_byte_3 lsl #0
28 #define put_byte_0 lsl #24
29 #define put_byte_1 lsl #16
30 #define put_byte_2 lsl #8
31 #define put_byte_3 lsl #0
32
33 #define PLD(code...)
34
35 #define MODE_USR USR_MODE
36 #define MODE_FIQ FIQ_MODE
37 #define MODE_IRQ IRQ_MODE
38 #define MODE_SVC SVC_MODE
39
40 #define DEFAULT_FIQ MODE_FIQ
41
42 /*
43 * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
44 */
45 #ifdef __STDC__
46 #define LOADREGS(cond, base, reglist...)\
47 ldm##cond base,reglist
48 #else
49 #define LOADREGS(cond, base, reglist...)\
50 ldm/**/cond base,reglist
51 #endif
52
53 /*
54 * Build a return instruction for this processor type.
55 */
56 #define RETINSTR(instr, regs...)\
57 instr regs
58
59 /*
60 * Enable and disable interrupts
61 */
62 .macro disable_irq
63 msr cpsr_c, #PSR_I_BIT | SVC_MODE
64 .endm
65
66 .macro enable_irq
67 msr cpsr_c, #SVC_MODE
68 .endm
69
70 /*
71 * Save the current IRQ state and disable IRQs. Note that this macro
72 * assumes FIQs are enabled, and that the processor is in SVC mode.
73 */
74 .macro save_and_disable_irqs, oldcpsr
75 mrs \oldcpsr, cpsr
76 disable_irq
77 .endm
78
79 /*
80 * Restore interrupt state previously stored in a register. We don't
81 * guarantee that this will preserve the flags.
82 */
83 .macro restore_irqs, oldcpsr
84 msr cpsr_c, \oldcpsr
85 .endm
86
87 /*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we do. On 32-bit
90 * architecture, we can safely ignore this requirement.
91 */
92 .macro save_lr
93 .endm
94
95 .macro restore_pc
96 mov pc, lr
97 .endm
98 ...
12 #include "bitops.h"
1 .macro bitop, instr
2 and r2, r0, #7
3 mov r3, #1
4 mov r3, r3, lsl r2
5 save_and_disable_irqs ip
6 ldrb r2, [r1, r0, lsr #3]
7 \instr r2, r2, r3
8 strb r2, [r1, r0, lsr #3]
9 restore_irqs ip
10 mov pc, lr
11 .endm
12
13 /**
14 * testop - implement a test_and_xxx_bit operation.
15 * @instr: operational instruction
16 * @store: store instruction
17 *
18 * Note: we can trivially conditionalise the store instruction
19 * to avoid dirting the data cache.
20 */
21 .macro testop, instr, store
22 add r1, r1, r0, lsr #3
23 and r3, r0, #7
24 mov r0, #1
25 save_and_disable_irqs ip
26 ldrb r2, [r1]
27 tst r2, r0, lsl r3
28 \instr r2, r2, r0, lsl r3
29 \store r2, [r1]
30 restore_irqs ip
31 moveq r0, #0
32 mov pc, lr
33 .endm
34 ...
13 .text
14
15 /*
16 * Purpose : Function to clear a bit
17 * Prototype: int clear_bit(int bit, void *addr)
18 */
19 ENTRY(_clear_bit_be)
20 0000 180020E2 eor r0, r0, #0x18 @ big endian byte ordering
21 ENTRY(_clear_bit_le)
22 0004 072000E2 bitop bic
22 0130A0E3
22 1332A0E1
22 00C00FE1
22 93F021E3
DEFINED SYMBOLS
lib/clearbit.S:19 .text:00000000 _clear_bit_be
lib/clearbit.S:19 .text:00000000 $a
lib/clearbit.S:21 .text:00000004 _clear_bit_le
.debug_aranges:0000000c $d
NO UNDEFINED SYMBOLS
+255
View File
@@ -0,0 +1,255 @@
/*
* linux/arch/arm/lib/copy_template.s
*
* Code template for optimized memory copy functions
*
* Author: Nicolas Pitre
* Created: Sep 28, 2005
* Copyright: MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/*
* This can be used to enable code to cacheline align the source pointer.
* Experiments on tested architectures (StrongARM and XScale) didn't show
* this a worthwhile thing to do. That might be different in the future.
*/
//#define CALGN(code...) code
#define CALGN(code...)
/*
* Theory of operation
* -------------------
*
* This file provides the core code for a forward memory copy used in
* the implementation of memcopy(), copy_to_user() and copy_from_user().
*
* The including file must define the following accessor macros
* according to the need of the given function:
*
* ldr1w ptr reg abort
*
* This loads one word from 'ptr', stores it in 'reg' and increments
* 'ptr' to the next word. The 'abort' argument is used for fixup tables.
*
* ldr4w ptr reg1 reg2 reg3 reg4 abort
* ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
*
* This loads four or eight words starting from 'ptr', stores them
* in provided registers and increments 'ptr' past those words.
* The'abort' argument is used for fixup tables.
*
* ldr1b ptr reg cond abort
*
* Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
* It also must apply the condition code if provided, otherwise the
* "al" condition is assumed by default.
*
* str1w ptr reg abort
* str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
* str1b ptr reg cond abort
*
* Same as their ldr* counterparts, but data is stored to 'ptr' location
* rather than being loaded.
*
* enter reg1 reg2
*
* Preserve the provided registers on the stack plus any additional
* data as needed by the implementation including this code. Called
* upon code entry.
*
* exit reg1 reg2
*
* Restore registers with the values previously saved with the
* 'preserv' macro. Called upon code termination.
*/
enter r4, lr
subs r2, r2, #4
blt 8f
ands ip, r0, #3
PLD( pld [r1, #0] )
bne 9f
ands ip, r1, #3
bne 10f
1: subs r2, r2, #(28)
stmfd sp!, {r5 - r8}
blt 5f
CALGN( ands ip, r1, #31 )
CALGN( rsb r3, ip, #32 )
CALGN( sbcnes r4, r3, r2 ) @ C is always set here
CALGN( bcs 2f )
CALGN( adr r4, 6f )
CALGN( subs r2, r2, r3 ) @ C gets set
CALGN( add pc, r4, ip )
PLD( pld [r1, #0] )
2: PLD( subs r2, r2, #96 )
PLD( pld [r1, #28] )
PLD( blt 4f )
PLD( pld [r1, #60] )
PLD( pld [r1, #92] )
3: PLD( pld [r1, #124] )
4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
subs r2, r2, #32
str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
bge 3b
PLD( cmn r2, #96 )
PLD( bge 4b )
5: ands ip, r2, #28
rsb ip, ip, #32
addne pc, pc, ip @ C is always clear here
b 7f
6: nop
ldr1w r1, r3, abort=20f
ldr1w r1, r4, abort=20f
ldr1w r1, r5, abort=20f
ldr1w r1, r6, abort=20f
ldr1w r1, r7, abort=20f
ldr1w r1, r8, abort=20f
ldr1w r1, lr, abort=20f
add pc, pc, ip
nop
nop
str1w r0, r3, abort=20f
str1w r0, r4, abort=20f
str1w r0, r5, abort=20f
str1w r0, r6, abort=20f
str1w r0, r7, abort=20f
str1w r0, r8, abort=20f
str1w r0, lr, abort=20f
CALGN( bcs 2b )
7: ldmfd sp!, {r5 - r8}
8: movs r2, r2, lsl #31
ldr1b r1, r3, ne, abort=21f
ldr1b r1, r4, cs, abort=21f
ldr1b r1, ip, cs, abort=21f
str1b r0, r3, ne, abort=21f
str1b r0, r4, cs, abort=21f
str1b r0, ip, cs, abort=21f
exit r4, pc
9: rsb ip, ip, #4
cmp ip, #2
ldr1b r1, r3, gt, abort=21f
ldr1b r1, r4, ge, abort=21f
ldr1b r1, lr, abort=21f
str1b r0, r3, gt, abort=21f
str1b r0, r4, ge, abort=21f
subs r2, r2, ip
str1b r0, lr, abort=21f
blt 8b
ands ip, r1, #3
beq 1b
10: bic r1, r1, #3
cmp ip, #2
ldr1w r1, lr, abort=21f
beq 17f
bgt 18f
.macro forward_copy_shift pull push
subs r2, r2, #28
blt 14f
CALGN( ands ip, r1, #31 )
CALGN( rsb ip, ip, #32 )
CALGN( sbcnes r4, ip, r2 ) @ C is always set here
CALGN( subcc r2, r2, ip )
CALGN( bcc 15f )
11: stmfd sp!, {r5 - r9}
PLD( pld [r1, #0] )
PLD( subs r2, r2, #96 )
PLD( pld [r1, #28] )
PLD( blt 13f )
PLD( pld [r1, #60] )
PLD( pld [r1, #92] )
12: PLD( pld [r1, #124] )
13: ldr4w r1, r4, r5, r6, r7, abort=19f
mov r3, lr, pull #\pull
subs r2, r2, #32
ldr4w r1, r8, r9, ip, lr, abort=19f
orr r3, r3, r4, push #\push
mov r4, r4, pull #\pull
orr r4, r4, r5, push #\push
mov r5, r5, pull #\pull
orr r5, r5, r6, push #\push
mov r6, r6, pull #\pull
orr r6, r6, r7, push #\push
mov r7, r7, pull #\pull
orr r7, r7, r8, push #\push
mov r8, r8, pull #\pull
orr r8, r8, r9, push #\push
mov r9, r9, pull #\pull
orr r9, r9, ip, push #\push
mov ip, ip, pull #\pull
orr ip, ip, lr, push #\push
str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
bge 12b
PLD( cmn r2, #96 )
PLD( bge 13b )
ldmfd sp!, {r5 - r9}
14: ands ip, r2, #28
beq 16f
15: mov r3, lr, pull #\pull
ldr1w r1, lr, abort=21f
subs ip, ip, #4
orr r3, r3, lr, push #\push
str1w r0, r3, abort=21f
bgt 15b
CALGN( cmp r2, #0 )
CALGN( bge 11b )
16: sub r1, r1, #(\push / 8)
b 8b
.endm
forward_copy_shift pull=8 push=24
17: forward_copy_shift pull=16 push=16
18: forward_copy_shift pull=24 push=8
/*
* Abort preamble and completion macros.
* If a fixup handler is required then those macros must surround it.
* It is assumed that the fixup code will handle the private part of
* the exit macro.
*/
.macro copy_abort_preamble
19: ldmfd sp!, {r5 - r9}
b 21f
20: ldmfd sp!, {r5 - r8}
21:
.endm
.macro copy_abort_end
ldmfd sp!, {r4, pc}
.endm
+34
View File
@@ -0,0 +1,34 @@
/*
* linux/lib/ctype.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <asm/ctype.h>
unsigned char _ctype[] = {
_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
+281
View File
@@ -0,0 +1,281 @@
1 .cpu arm7tdmi
2 .fpu softvfp
3 .eabi_attribute 20, 1
4 .eabi_attribute 21, 1
5 .eabi_attribute 23, 3
6 .eabi_attribute 24, 1
7 .eabi_attribute 25, 1
8 .eabi_attribute 26, 1
9 .eabi_attribute 30, 4
10 .eabi_attribute 18, 4
11 .file "ctype.c"
19 .Ltext0:
20 .cfi_sections .debug_frame
21 .global _ctype
22 .data
25 _ctype:
26 0000 08 .byte 8
27 0001 08 .byte 8
28 0002 08 .byte 8
29 0003 08 .byte 8
30 0004 08 .byte 8
31 0005 08 .byte 8
32 0006 08 .byte 8
33 0007 08 .byte 8
34 0008 08 .byte 8
35 0009 28 .byte 40
36 000a 28 .byte 40
37 000b 28 .byte 40
38 000c 28 .byte 40
39 000d 28 .byte 40
40 000e 08 .byte 8
41 000f 08 .byte 8
42 0010 08 .byte 8
43 0011 08 .byte 8
44 0012 08 .byte 8
45 0013 08 .byte 8
46 0014 08 .byte 8
47 0015 08 .byte 8
48 0016 08 .byte 8
49 0017 08 .byte 8
50 0018 08 .byte 8
51 0019 08 .byte 8
52 001a 08 .byte 8
53 001b 08 .byte 8
54 001c 08 .byte 8
55 001d 08 .byte 8
56 001e 08 .byte 8
57 001f 08 .byte 8
58 0020 A0 .byte -96
59 0021 10 .byte 16
60 0022 10 .byte 16
61 0023 10 .byte 16
62 0024 10 .byte 16
63 0025 10 .byte 16
64 0026 10 .byte 16
65 0027 10 .byte 16
66 0028 10 .byte 16
67 0029 10 .byte 16
68 002a 10 .byte 16
69 002b 10 .byte 16
70 002c 10 .byte 16
71 002d 10 .byte 16
72 002e 10 .byte 16
73 002f 10 .byte 16
74 0030 04 .byte 4
75 0031 04 .byte 4
76 0032 04 .byte 4
77 0033 04 .byte 4
78 0034 04 .byte 4
79 0035 04 .byte 4
80 0036 04 .byte 4
81 0037 04 .byte 4
82 0038 04 .byte 4
83 0039 04 .byte 4
84 003a 10 .byte 16
85 003b 10 .byte 16
86 003c 10 .byte 16
87 003d 10 .byte 16
88 003e 10 .byte 16
89 003f 10 .byte 16
90 0040 10 .byte 16
91 0041 41 .byte 65
92 0042 41 .byte 65
93 0043 41 .byte 65
94 0044 41 .byte 65
95 0045 41 .byte 65
96 0046 41 .byte 65
97 0047 01 .byte 1
98 0048 01 .byte 1
99 0049 01 .byte 1
100 004a 01 .byte 1
101 004b 01 .byte 1
102 004c 01 .byte 1
103 004d 01 .byte 1
104 004e 01 .byte 1
105 004f 01 .byte 1
106 0050 01 .byte 1
107 0051 01 .byte 1
108 0052 01 .byte 1
109 0053 01 .byte 1
110 0054 01 .byte 1
111 0055 01 .byte 1
112 0056 01 .byte 1
113 0057 01 .byte 1
114 0058 01 .byte 1
115 0059 01 .byte 1
116 005a 01 .byte 1
117 005b 10 .byte 16
118 005c 10 .byte 16
119 005d 10 .byte 16
120 005e 10 .byte 16
121 005f 10 .byte 16
122 0060 10 .byte 16
123 0061 42 .byte 66
124 0062 42 .byte 66
125 0063 42 .byte 66
126 0064 42 .byte 66
127 0065 42 .byte 66
128 0066 42 .byte 66
129 0067 02 .byte 2
130 0068 02 .byte 2
131 0069 02 .byte 2
132 006a 02 .byte 2
133 006b 02 .byte 2
134 006c 02 .byte 2
135 006d 02 .byte 2
136 006e 02 .byte 2
137 006f 02 .byte 2
138 0070 02 .byte 2
139 0071 02 .byte 2
140 0072 02 .byte 2
141 0073 02 .byte 2
142 0074 02 .byte 2
143 0075 02 .byte 2
144 0076 02 .byte 2
145 0077 02 .byte 2
146 0078 02 .byte 2
147 0079 02 .byte 2
148 007a 02 .byte 2
149 007b 10 .byte 16
150 007c 10 .byte 16
151 007d 10 .byte 16
152 007e 10 .byte 16
153 007f 08 .byte 8
154 0080 00 .byte 0
155 0081 00 .byte 0
156 0082 00 .byte 0
157 0083 00 .byte 0
158 0084 00 .byte 0
159 0085 00 .byte 0
160 0086 00 .byte 0
161 0087 00 .byte 0
162 0088 00 .byte 0
163 0089 00 .byte 0
164 008a 00 .byte 0
165 008b 00 .byte 0
166 008c 00 .byte 0
167 008d 00 .byte 0
168 008e 00 .byte 0
169 008f 00 .byte 0
170 0090 00 .byte 0
171 0091 00 .byte 0
172 0092 00 .byte 0
173 0093 00 .byte 0
174 0094 00 .byte 0
175 0095 00 .byte 0
176 0096 00 .byte 0
177 0097 00 .byte 0
178 0098 00 .byte 0
179 0099 00 .byte 0
180 009a 00 .byte 0
181 009b 00 .byte 0
182 009c 00 .byte 0
183 009d 00 .byte 0
184 009e 00 .byte 0
185 009f 00 .byte 0
186 00a0 A0 .byte -96
187 00a1 10 .byte 16
188 00a2 10 .byte 16
189 00a3 10 .byte 16
190 00a4 10 .byte 16
191 00a5 10 .byte 16
192 00a6 10 .byte 16
193 00a7 10 .byte 16
194 00a8 10 .byte 16
195 00a9 10 .byte 16
196 00aa 10 .byte 16
197 00ab 10 .byte 16
198 00ac 10 .byte 16
199 00ad 10 .byte 16
200 00ae 10 .byte 16
201 00af 10 .byte 16
202 00b0 10 .byte 16
203 00b1 10 .byte 16
204 00b2 10 .byte 16
205 00b3 10 .byte 16
206 00b4 10 .byte 16
207 00b5 10 .byte 16
208 00b6 10 .byte 16
209 00b7 10 .byte 16
210 00b8 10 .byte 16
211 00b9 10 .byte 16
212 00ba 10 .byte 16
213 00bb 10 .byte 16
214 00bc 10 .byte 16
215 00bd 10 .byte 16
216 00be 10 .byte 16
217 00bf 10 .byte 16
218 00c0 01 .byte 1
219 00c1 01 .byte 1
220 00c2 01 .byte 1
221 00c3 01 .byte 1
222 00c4 01 .byte 1
223 00c5 01 .byte 1
224 00c6 01 .byte 1
225 00c7 01 .byte 1
226 00c8 01 .byte 1
227 00c9 01 .byte 1
228 00ca 01 .byte 1
229 00cb 01 .byte 1
230 00cc 01 .byte 1
231 00cd 01 .byte 1
232 00ce 01 .byte 1
233 00cf 01 .byte 1
234 00d0 01 .byte 1
235 00d1 01 .byte 1
236 00d2 01 .byte 1
237 00d3 01 .byte 1
238 00d4 01 .byte 1
239 00d5 01 .byte 1
240 00d6 01 .byte 1
241 00d7 10 .byte 16
242 00d8 01 .byte 1
243 00d9 01 .byte 1
244 00da 01 .byte 1
245 00db 01 .byte 1
246 00dc 01 .byte 1
247 00dd 01 .byte 1
248 00de 01 .byte 1
249 00df 02 .byte 2
250 00e0 02 .byte 2
251 00e1 02 .byte 2
252 00e2 02 .byte 2
253 00e3 02 .byte 2
254 00e4 02 .byte 2
255 00e5 02 .byte 2
256 00e6 02 .byte 2
257 00e7 02 .byte 2
258 00e8 02 .byte 2
259 00e9 02 .byte 2
260 00ea 02 .byte 2
261 00eb 02 .byte 2
262 00ec 02 .byte 2
263 00ed 02 .byte 2
264 00ee 02 .byte 2
265 00ef 02 .byte 2
266 00f0 02 .byte 2
267 00f1 02 .byte 2
268 00f2 02 .byte 2
269 00f3 02 .byte 2
270 00f4 02 .byte 2
271 00f5 02 .byte 2
272 00f6 02 .byte 2
273 00f7 10 .byte 16
274 00f8 02 .byte 2
275 00f9 02 .byte 2
276 00fa 02 .byte 2
277 00fb 02 .byte 2
278 00fc 02 .byte 2
279 00fd 02 .byte 2
280 00fe 02 .byte 2
281 00ff 02 .byte 2
282 .text
283 .Letext0:
284 .file 1 "include/asm/ctype.h"
285 .file 2 "lib/ctype.c"
DEFINED SYMBOLS
*ABS*:00000000 ctype.c
C:\Users\netz\AppData\Local\Temp\cc1cqvvg.s:25 .data:00000000 _ctype
NO UNDEFINED SYMBOLS
+200
View File
@@ -0,0 +1,200 @@
/*
* linux/arch/arm/lib/div64.S
*
* Optimized computation of 64-bit dividend / 32-bit divisor
*
* Author: Nicolas Pitre
* Created: Oct 5, 2003
* Copyright: Monta Vista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#ifdef __ARMEB__
#define xh r0
#define xl r1
#define yh r2
#define yl r3
#else
#define xl r0
#define xh r1
#define yl r2
#define yh r3
#endif
/*
* __do_div64: perform a division with 64-bit dividend and 32-bit divisor.
*
* Note: Calling convention is totally non standard for optimal code.
* This is meant to be used by do_div() from include/asm/div64.h only.
*
* Input parameters:
* xh-xl = dividend (clobbered)
* r4 = divisor (preserved)
*
* Output values:
* yh-yl = result
* xh = remainder
*
* Clobbered regs: xl, ip
*/
ENTRY(__do_div64)
@ Test for easy paths first.
subs ip, r4, #1
bls 9f @ divisor is 0 or 1
tst ip, r4
beq 8f @ divisor is power of 2
@ See if we need to handle upper 32-bit result.
cmp xh, r4
mov yh, #0
blo 3f
@ Align divisor with upper part of dividend.
@ The aligned divisor is stored in yl preserving the original.
@ The bit position is stored in ip.
#if __LINUX_ARM_ARCH__ >= 5
clz yl, r4
clz ip, xh
sub yl, yl, ip
mov ip, #1
mov ip, ip, lsl yl
mov yl, r4, lsl yl
#else
mov yl, r4
mov ip, #1
1: cmp yl, #0x80000000
cmpcc yl, xh
movcc yl, yl, lsl #1
movcc ip, ip, lsl #1
bcc 1b
#endif
@ The division loop for needed upper bit positions.
@ Break out early if dividend reaches 0.
2: cmp xh, yl
orrcs yh, yh, ip
subcss xh, xh, yl
movnes ip, ip, lsr #1
mov yl, yl, lsr #1
bne 2b
@ See if we need to handle lower 32-bit result.
3: cmp xh, #0
mov yl, #0
cmpeq xl, r4
movlo xh, xl
movlo pc, lr
@ The division loop for lower bit positions.
@ Here we shift remainer bits leftwards rather than moving the
@ divisor for comparisons, considering the carry-out bit as well.
mov ip, #0x80000000
4: movs xl, xl, lsl #1
adcs xh, xh, xh
beq 6f
cmpcc xh, r4
5: orrcs yl, yl, ip
subcs xh, xh, r4
movs ip, ip, lsr #1
bne 4b
mov pc, lr
@ The top part of remainder became zero. If carry is set
@ (the 33th bit) this is a false positive so resume the loop.
@ Otherwise, if lower part is also null then we are done.
6: bcs 5b
cmp xl, #0
moveq pc, lr
@ We still have remainer bits in the low part. Bring them up.
#if __LINUX_ARM_ARCH__ >= 5
clz xh, xl @ we know xh is zero here so...
add xh, xh, #1
mov xl, xl, lsl xh
mov ip, ip, lsr xh
#else
7: movs xl, xl, lsl #1
mov ip, ip, lsr #1
bcc 7b
#endif
@ Current remainder is now 1. It is worthless to compare with
@ divisor at this point since divisor can not be smaller than 3 here.
@ If possible, branch for another shift in the division loop.
@ If no bit position left then we are done.
movs ip, ip, lsr #1
mov xh, #1
bne 4b
mov pc, lr
8: @ Division by a power of 2: determine what that divisor order is
@ then simply shift values around
#if __LINUX_ARM_ARCH__ >= 5
clz ip, r4
rsb ip, ip, #31
#else
mov yl, r4
cmp r4, #(1 << 16)
mov ip, #0
movhs yl, yl, lsr #16
movhs ip, #16
cmp yl, #(1 << 8)
movhs yl, yl, lsr #8
addhs ip, ip, #8
cmp yl, #(1 << 4)
movhs yl, yl, lsr #4
addhs ip, ip, #4
cmp yl, #(1 << 2)
addhi ip, ip, #3
addls ip, ip, yl, lsr #1
#endif
mov yh, xh, lsr ip
mov yl, xl, lsr ip
rsb ip, ip, #32
orr yl, yl, xh, lsl ip
mov xh, xl, lsl ip
mov xh, xh, lsr ip
mov pc, lr
@ eq -> division by 1: obvious enough...
9: moveq yl, xl
moveq yh, xh
moveq xh, #0
moveq pc, lr
@ Division by 0:
str lr, [sp, #-8]!
bl __div0
@ as wrong as it could be...
mov yl, #0
mov yh, #0
mov xh, #0
ldr pc, [sp], #8
+210
View File
@@ -0,0 +1,210 @@
1 # 1 "lib/div64.S"
1 /*
0
0
2 * linux/arch/arm/lib/div64.S
3 *
4 * Optimized computation of 64-bit dividend / 32-bit divisor
5 *
6 * Author: Nicolas Pitre
7 * Created: Oct 5, 2003
8 * Copyright: Monta Vista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
16
17 #ifdef __ARMEB__
18 #define xh r0
19 #define xl r1
20 #define yh r2
21 #define yl r3
22 #else
23 #define xl r0
24 #define xh r1
25 #define yl r2
26 #define yh r3
27 #endif
28
29 /*
30 * __do_div64: perform a division with 64-bit dividend and 32-bit divisor.
31 *
32 * Note: Calling convention is totally non standard for optimal code.
33 * This is meant to be used by do_div() from include/asm/div64.h only.
34 *
35 * Input parameters:
36 * xh-xl = dividend (clobbered)
37 * r4 = divisor (preserved)
38 *
39 * Output values:
40 * yh-yl = result
41 * xh = remainder
42 *
43 * Clobbered regs: xl, ip
44 */
45
46 ENTRY(__do_div64)
47
48 @ Test for easy paths first.
49 0000 01C054E2 subs ip, r4, #1
50 0004 3F00009A bls 9f @ divisor is 0 or 1
51 0008 04001CE1 tst ip, r4
52 000c 2800000A beq 8f @ divisor is power of 2
53
54 @ See if we need to handle upper 32-bit result.
55 0010 040051E1 cmp xh, r4
56 0014 0030A0E3 mov yh, #0
57 0018 0C00003A blo 3f
58
59 @ Align divisor with upper part of dividend.
60 @ The aligned divisor is stored in yl preserving the original.
61 @ The bit position is stored in ip.
62
63 #if __LINUX_ARM_ARCH__ >= 5
64
65 clz yl, r4
66 clz ip, xh
67 sub yl, yl, ip
68 mov ip, #1
69 mov ip, ip, lsl yl
70 mov yl, r4, lsl yl
71
72 #else
73
74 001c 0420A0E1 mov yl, r4
75 0020 01C0A0E3 mov ip, #1
76 0024 020152E3 1: cmp yl, #0x80000000
77 0028 01005231 cmpcc yl, xh
78 002c 8220A031 movcc yl, yl, lsl #1
79 0030 8CC0A031 movcc ip, ip, lsl #1
80 0034 FAFFFF3A bcc 1b
81
82 #endif
83
84 @ The division loop for needed upper bit positions.
85 @ Break out early if dividend reaches 0.
86 0038 020051E1 2: cmp xh, yl
87 003c 0C308321 orrcs yh, yh, ip
88 0040 02105120 subcss xh, xh, yl
89 0044 ACC0B011 movnes ip, ip, lsr #1
90 0048 A220A0E1 mov yl, yl, lsr #1
91 004c F9FFFF1A bne 2b
92
93 @ See if we need to handle lower 32-bit result.
94 0050 000051E3 3: cmp xh, #0
95 0054 0020A0E3 mov yl, #0
96 0058 04005001 cmpeq xl, r4
97 005c 0010A031 movlo xh, xl
98 0060 0EF0A031 movlo pc, lr
99
100 @ The division loop for lower bit positions.
101 @ Here we shift remainer bits leftwards rather than moving the
102 @ divisor for comparisons, considering the carry-out bit as well.
103 0064 02C1A0E3 mov ip, #0x80000000
104 0068 8000B0E1 4: movs xl, xl, lsl #1
105 006c 0110B1E0 adcs xh, xh, xh
106 0070 0500000A beq 6f
107 0074 04005131 cmpcc xh, r4
108 0078 0C208221 5: orrcs yl, yl, ip
109 007c 04104120 subcs xh, xh, r4
110 0080 ACC0B0E1 movs ip, ip, lsr #1
111 0084 F7FFFF1A bne 4b
112 0088 0EF0A0E1 mov pc, lr
113
114 @ The top part of remainder became zero. If carry is set
115 @ (the 33th bit) this is a false positive so resume the loop.
116 @ Otherwise, if lower part is also null then we are done.
117 008c F9FFFF2A 6: bcs 5b
118 0090 000050E3 cmp xl, #0
119 0094 0EF0A001 moveq pc, lr
120
121 @ We still have remainer bits in the low part. Bring them up.
122
123 #if __LINUX_ARM_ARCH__ >= 5
124
125 clz xh, xl @ we know xh is zero here so...
126 add xh, xh, #1
127 mov xl, xl, lsl xh
128 mov ip, ip, lsr xh
129
130 #else
131
132 0098 8000B0E1 7: movs xl, xl, lsl #1
133 009c ACC0A0E1 mov ip, ip, lsr #1
134 00a0 FCFFFF3A bcc 7b
135
136 #endif
137
138 @ Current remainder is now 1. It is worthless to compare with
139 @ divisor at this point since divisor can not be smaller than 3 here.
140 @ If possible, branch for another shift in the division loop.
141 @ If no bit position left then we are done.
142 00a4 ACC0B0E1 movs ip, ip, lsr #1
143 00a8 0110A0E3 mov xh, #1
144 00ac EDFFFF1A bne 4b
145 00b0 0EF0A0E1 mov pc, lr
146
147 8: @ Division by a power of 2: determine what that divisor order is
148 @ then simply shift values around
149
150 #if __LINUX_ARM_ARCH__ >= 5
151
152 clz ip, r4
153 rsb ip, ip, #31
154
155 #else
156
157 00b4 0420A0E1 mov yl, r4
158 00b8 010854E3 cmp r4, #(1 << 16)
159 00bc 00C0A0E3 mov ip, #0
160 00c0 2228A021 movhs yl, yl, lsr #16
161 00c4 10C0A023 movhs ip, #16
162
163 00c8 010C52E3 cmp yl, #(1 << 8)
164 00cc 2224A021 movhs yl, yl, lsr #8
165 00d0 08C08C22 addhs ip, ip, #8
166
167 00d4 100052E3 cmp yl, #(1 << 4)
168 00d8 2222A021 movhs yl, yl, lsr #4
169 00dc 04C08C22 addhs ip, ip, #4
170
171 00e0 040052E3 cmp yl, #(1 << 2)
172 00e4 03C08C82 addhi ip, ip, #3
173 00e8 A2C08C90 addls ip, ip, yl, lsr #1
174
175 #endif
176
177 00ec 313CA0E1 mov yh, xh, lsr ip
178 00f0 302CA0E1 mov yl, xl, lsr ip
179 00f4 20C06CE2 rsb ip, ip, #32
180 00f8 112C82E1 orr yl, yl, xh, lsl ip
181 00fc 101CA0E1 mov xh, xl, lsl ip
182 0100 311CA0E1 mov xh, xh, lsr ip
183 0104 0EF0A0E1 mov pc, lr
184
185 @ eq -> division by 1: obvious enough...
186 0108 0020A001 9: moveq yl, xl
187 010c 0130A001 moveq yh, xh
188 0110 0010A003 moveq xh, #0
189 0114 0EF0A001 moveq pc, lr
190
191 @ Division by 0:
192 0118 08E02DE5 str lr, [sp, #-8]!
193 011c FEFFFFEB bl __div0
194
195 @ as wrong as it could be...
196 0120 0020A0E3 mov yl, #0
197 0124 0030A0E3 mov yh, #0
198 0128 0010A0E3 mov xh, #0
199 012c 08F09DE4 ldr pc, [sp], #8
DEFINED SYMBOLS
lib/div64.S:46 .text:00000000 __do_div64
lib/div64.S:46 .text:00000000 $a
.debug_aranges:0000000c $d
UNDEFINED SYMBOLS
__div0
+338
View File
@@ -0,0 +1,338 @@
/*
* linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
*
* Author: Nicolas Pitre <nico@cam.org>
* - contributed to gcc-3.4 on Sep 30, 2003
* - adapted for the Linux kernel on Oct 2, 2003
*/
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <asm/linkage.h>
#include <asm/assembler.h>
.macro ARM_DIV_BODY dividend, divisor, result, curbit
#if __LINUX_ARM_ARCH__ >= 5
clz \curbit, \divisor
clz \result, \dividend
sub \result, \curbit, \result
mov \curbit, #1
mov \divisor, \divisor, lsl \result
mov \curbit, \curbit, lsl \result
mov \result, #0
#else
@ Initially shift the divisor left 3 bits if possible,
@ set curbit accordingly. This allows for curbit to be located
@ at the left end of each 4 bit nibbles in the division loop
@ to save one loop in most cases.
tst \divisor, #0xe0000000
moveq \divisor, \divisor, lsl #3
moveq \curbit, #8
movne \curbit, #1
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
1: cmp \divisor, #0x10000000
cmplo \divisor, \dividend
movlo \divisor, \divisor, lsl #4
movlo \curbit, \curbit, lsl #4
blo 1b
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
1: cmp \divisor, #0x80000000
cmplo \divisor, \dividend
movlo \divisor, \divisor, lsl #1
movlo \curbit, \curbit, lsl #1
blo 1b
mov \result, #0
#endif
@ Division loop
1: cmp \dividend, \divisor
subhs \dividend, \dividend, \divisor
orrhs \result, \result, \curbit
cmp \dividend, \divisor, lsr #1
subhs \dividend, \dividend, \divisor, lsr #1
orrhs \result, \result, \curbit, lsr #1
cmp \dividend, \divisor, lsr #2
subhs \dividend, \dividend, \divisor, lsr #2
orrhs \result, \result, \curbit, lsr #2
cmp \dividend, \divisor, lsr #3
subhs \dividend, \dividend, \divisor, lsr #3
orrhs \result, \result, \curbit, lsr #3
cmp \dividend, #0 @ Early termination?
movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
movne \divisor, \divisor, lsr #4
bne 1b
.endm
.macro ARM_DIV2_ORDER divisor, order
#if __LINUX_ARM_ARCH__ >= 5
clz \order, \divisor
rsb \order, \order, #31
#else
cmp \divisor, #(1 << 16)
movhs \divisor, \divisor, lsr #16
movhs \order, #16
movlo \order, #0
cmp \divisor, #(1 << 8)
movhs \divisor, \divisor, lsr #8
addhs \order, \order, #8
cmp \divisor, #(1 << 4)
movhs \divisor, \divisor, lsr #4
addhs \order, \order, #4
cmp \divisor, #(1 << 2)
addhi \order, \order, #3
addls \order, \order, \divisor, lsr #1
#endif
.endm
.macro ARM_MOD_BODY dividend, divisor, order, spare
#if __LINUX_ARM_ARCH__ >= 5
clz \order, \divisor
clz \spare, \dividend
sub \order, \order, \spare
mov \divisor, \divisor, lsl \order
#else
mov \order, #0
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
1: cmp \divisor, #0x10000000
cmplo \divisor, \dividend
movlo \divisor, \divisor, lsl #4
addlo \order, \order, #4
blo 1b
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
1: cmp \divisor, #0x80000000
cmplo \divisor, \dividend
movlo \divisor, \divisor, lsl #1
addlo \order, \order, #1
blo 1b
#endif
@ Perform all needed substractions to keep only the reminder.
@ Do comparisons in batch of 4 first.
subs \order, \order, #3 @ yes, 3 is intended here
blt 2f
1: cmp \dividend, \divisor
subhs \dividend, \dividend, \divisor
cmp \dividend, \divisor, lsr #1
subhs \dividend, \dividend, \divisor, lsr #1
cmp \dividend, \divisor, lsr #2
subhs \dividend, \dividend, \divisor, lsr #2
cmp \dividend, \divisor, lsr #3
subhs \dividend, \dividend, \divisor, lsr #3
cmp \dividend, #1
mov \divisor, \divisor, lsr #4
subges \order, \order, #4
bge 1b
tst \order, #3
teqne \dividend, #0
beq 5f
@ Either 1, 2 or 3 comparison/substractions are left.
2: cmn \order, #2
blt 4f
beq 3f
cmp \dividend, \divisor
subhs \dividend, \dividend, \divisor
mov \divisor, \divisor, lsr #1
3: cmp \dividend, \divisor
subhs \dividend, \dividend, \divisor
mov \divisor, \divisor, lsr #1
4: cmp \dividend, \divisor
subhs \dividend, \dividend, \divisor
5:
.endm
/*ENTRY(__udivsi3)
ENTRY(__aeabi_uidiv)
subs r2, r1, #1
moveq pc, lr
bcc Ldiv0
cmp r0, r1
bls 11f
tst r1, r2
beq 12f
ARM_DIV_BODY r0, r1, r2, r3
mov r0, r2
mov pc, lr
11: moveq r0, #1
movne r0, #0
mov pc, lr
12: ARM_DIV2_ORDER r1, r2
mov r0, r0, lsr r2
mov pc, lr
*/
ENTRY(__umodsi3)
subs r2, r1, #1 @ compare divisor with 1
bcc Ldiv0
cmpne r0, r1 @ compare dividend with divisor
moveq r0, #0
tsthi r1, r2 @ see if divisor is power of 2
andeq r0, r0, r2
movls pc, lr
ARM_MOD_BODY r0, r1, r2, r3
mov pc, lr
ENTRY(__divsi3)
ENTRY(__aeabi_idiv)
cmp r1, #0
eor ip, r0, r1 @ save the sign of the result.
beq Ldiv0
rsbmi r1, r1, #0 @ loops below use unsigned.
subs r2, r1, #1 @ division by 1 or -1 ?
beq 10f
movs r3, r0
rsbmi r3, r0, #0 @ positive dividend value
cmp r3, r1
bls 11f
tst r1, r2 @ divisor is power of 2 ?
beq 12f
ARM_DIV_BODY r3, r1, r0, r2
cmp ip, #0
rsbmi r0, r0, #0
mov pc, lr
10: teq ip, r0 @ same sign ?
rsbmi r0, r0, #0
mov pc, lr
11: movlo r0, #0
moveq r0, ip, asr #31
orreq r0, r0, #1
mov pc, lr
12: ARM_DIV2_ORDER r1, r2
cmp ip, #0
mov r0, r3, lsr r2
rsbmi r0, r0, #0
mov pc, lr
ENTRY(__modsi3)
cmp r1, #0
beq Ldiv0
rsbmi r1, r1, #0 @ loops below use unsigned.
movs ip, r0 @ preserve sign of dividend
rsbmi r0, r0, #0 @ if negative make positive
subs r2, r1, #1 @ compare divisor with 1
cmpne r0, r1 @ compare dividend with divisor
moveq r0, #0
tsthi r1, r2 @ see if divisor is power of 2
andeq r0, r0, r2
bls 10f
ARM_MOD_BODY r0, r1, r2, r3
10: cmp ip, #0
rsbmi r0, r0, #0
mov pc, lr
#ifdef CONFIG_AEABI
ENTRY(__aeabi_uidivmod)
stmfd sp!, {r0, r1, ip, lr}
bl __aeabi_uidiv
ldmfd sp!, {r1, r2, ip, lr}
mul r3, r0, r2
sub r1, r1, r3
mov pc, lr
ENTRY(__aeabi_idivmod)
stmfd sp!, {r0, r1, ip, lr}
bl __aeabi_idiv
ldmfd sp!, {r1, r2, ip, lr}
mul r3, r0, r2
sub r1, r1, r3
mov pc, lr
#endif
Ldiv0:
str lr, [sp, #-8]!
bl __div0
mov r0, #0 @ About as wrong as it could be.
ldr pc, [sp], #8
ENTRY(__div0)
mov pc, lr
+452
View File
@@ -0,0 +1,452 @@
1 # 1 "lib/lib1funcs.S"
1 /*
0
0
2 * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
3 *
4 * Author: Nicolas Pitre <nico@cam.org>
5 * - contributed to gcc-3.4 on Sep 30, 2003
6 * - adapted for the Linux kernel on Oct 2, 2003
7 */
8
9 /* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
10
11 This file is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2, or (at your option) any
14 later version.
15
16 In addition to the permissions in the GNU General Public License, the
17 Free Software Foundation gives you unlimited permission to link the
18 compiled version of this file into combinations with other programs,
19 and to distribute those combinations without any restriction coming
20 from the use of this file. (The General Public License restrictions
21 do apply in other respects; for example, they cover modification of
22 the file, and distribution when not linked into a combine
23 executable.)
24
25 This file is distributed in the hope that it will be useful, but
26 WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; see the file COPYING. If not, write to
32 the Free Software Foundation, 59 Temple Place - Suite 330,
33 Boston, MA 02111-1307, USA. */
34
35
36 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
37 #include <asm/assembler.h>
1 /*
2 * linux/include/asm-arm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16 #ifndef __ASSEMBLY__
17 #error "Only include this from assembly code"
18 #endif
19
20 #include <asm/ptrace.h>
1 /*
21
22 #define pull lsl
23 #define push lsr
24 #define get_byte_0 lsr #24
25 #define get_byte_1 lsr #16
26 #define get_byte_2 lsr #8
27 #define get_byte_3 lsl #0
28 #define put_byte_0 lsl #24
29 #define put_byte_1 lsl #16
30 #define put_byte_2 lsl #8
31 #define put_byte_3 lsl #0
32
33 #define PLD(code...)
34
35 #define MODE_USR USR_MODE
36 #define MODE_FIQ FIQ_MODE
37 #define MODE_IRQ IRQ_MODE
38 #define MODE_SVC SVC_MODE
39
40 #define DEFAULT_FIQ MODE_FIQ
41
42 /*
43 * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
44 */
45 #ifdef __STDC__
46 #define LOADREGS(cond, base, reglist...)\
47 ldm##cond base,reglist
48 #else
49 #define LOADREGS(cond, base, reglist...)\
50 ldm/**/cond base,reglist
51 #endif
52
53 /*
54 * Build a return instruction for this processor type.
55 */
56 #define RETINSTR(instr, regs...)\
57 instr regs
58
59 /*
60 * Enable and disable interrupts
61 */
62 .macro disable_irq
63 msr cpsr_c, #PSR_I_BIT | SVC_MODE
64 .endm
65
66 .macro enable_irq
67 msr cpsr_c, #SVC_MODE
68 .endm
69
70 /*
71 * Save the current IRQ state and disable IRQs. Note that this macro
72 * assumes FIQs are enabled, and that the processor is in SVC mode.
73 */
74 .macro save_and_disable_irqs, oldcpsr
75 mrs \oldcpsr, cpsr
76 disable_irq
77 .endm
78
79 /*
80 * Restore interrupt state previously stored in a register. We don't
81 * guarantee that this will preserve the flags.
82 */
83 .macro restore_irqs, oldcpsr
84 msr cpsr_c, \oldcpsr
85 .endm
86
87 /*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we do. On 32-bit
90 * architecture, we can safely ignore this requirement.
91 */
92 .macro save_lr
93 .endm
94
95 .macro restore_pc
96 mov pc, lr
97 .endm
98 ...
38
39
40 .macro ARM_DIV_BODY dividend, divisor, result, curbit
41
42 #if __LINUX_ARM_ARCH__ >= 5
43
44 clz \curbit, \divisor
45 clz \result, \dividend
46 sub \result, \curbit, \result
47 mov \curbit, #1
48 mov \divisor, \divisor, lsl \result
49 mov \curbit, \curbit, lsl \result
50 mov \result, #0
51
52 #else
53
54 @ Initially shift the divisor left 3 bits if possible,
55 @ set curbit accordingly. This allows for curbit to be located
56 @ at the left end of each 4 bit nibbles in the division loop
57 @ to save one loop in most cases.
58 tst \divisor, #0xe0000000
59 moveq \divisor, \divisor, lsl #3
60 moveq \curbit, #8
61 movne \curbit, #1
62
63 @ Unless the divisor is very big, shift it up in multiples of
64 @ four bits, since this is the amount of unwinding in the main
65 @ division loop. Continue shifting until the divisor is
66 @ larger than the dividend.
67 1: cmp \divisor, #0x10000000
68 cmplo \divisor, \dividend
69 movlo \divisor, \divisor, lsl #4
70 movlo \curbit, \curbit, lsl #4
71 blo 1b
72
73 @ For very big divisors, we must shift it a bit at a time, or
74 @ we will be in danger of overflowing.
75 1: cmp \divisor, #0x80000000
76 cmplo \divisor, \dividend
77 movlo \divisor, \divisor, lsl #1
78 movlo \curbit, \curbit, lsl #1
79 blo 1b
80
81 mov \result, #0
82
83 #endif
84
85 @ Division loop
86 1: cmp \dividend, \divisor
87 subhs \dividend, \dividend, \divisor
88 orrhs \result, \result, \curbit
89 cmp \dividend, \divisor, lsr #1
90 subhs \dividend, \dividend, \divisor, lsr #1
91 orrhs \result, \result, \curbit, lsr #1
92 cmp \dividend, \divisor, lsr #2
93 subhs \dividend, \dividend, \divisor, lsr #2
94 orrhs \result, \result, \curbit, lsr #2
95 cmp \dividend, \divisor, lsr #3
96 subhs \dividend, \dividend, \divisor, lsr #3
97 orrhs \result, \result, \curbit, lsr #3
98 cmp \dividend, #0 @ Early termination?
99 movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
100 movne \divisor, \divisor, lsr #4
101 bne 1b
102
103 .endm
104
105
106 .macro ARM_DIV2_ORDER divisor, order
107
108 #if __LINUX_ARM_ARCH__ >= 5
109
110 clz \order, \divisor
111 rsb \order, \order, #31
112
113 #else
114
115 cmp \divisor, #(1 << 16)
116 movhs \divisor, \divisor, lsr #16
117 movhs \order, #16
118 movlo \order, #0
119
120 cmp \divisor, #(1 << 8)
121 movhs \divisor, \divisor, lsr #8
122 addhs \order, \order, #8
123
124 cmp \divisor, #(1 << 4)
125 movhs \divisor, \divisor, lsr #4
126 addhs \order, \order, #4
127
128 cmp \divisor, #(1 << 2)
129 addhi \order, \order, #3
130 addls \order, \order, \divisor, lsr #1
131
132 #endif
133
134 .endm
135
136
137 .macro ARM_MOD_BODY dividend, divisor, order, spare
138
139 #if __LINUX_ARM_ARCH__ >= 5
140
141 clz \order, \divisor
142 clz \spare, \dividend
143 sub \order, \order, \spare
144 mov \divisor, \divisor, lsl \order
145
146 #else
147
148 mov \order, #0
149
150 @ Unless the divisor is very big, shift it up in multiples of
151 @ four bits, since this is the amount of unwinding in the main
152 @ division loop. Continue shifting until the divisor is
153 @ larger than the dividend.
154 1: cmp \divisor, #0x10000000
155 cmplo \divisor, \dividend
156 movlo \divisor, \divisor, lsl #4
157 addlo \order, \order, #4
158 blo 1b
159
160 @ For very big divisors, we must shift it a bit at a time, or
161 @ we will be in danger of overflowing.
162 1: cmp \divisor, #0x80000000
163 cmplo \divisor, \dividend
164 movlo \divisor, \divisor, lsl #1
165 addlo \order, \order, #1
166 blo 1b
167
168 #endif
169
170 @ Perform all needed substractions to keep only the reminder.
171 @ Do comparisons in batch of 4 first.
172 subs \order, \order, #3 @ yes, 3 is intended here
173 blt 2f
174
175 1: cmp \dividend, \divisor
176 subhs \dividend, \dividend, \divisor
177 cmp \dividend, \divisor, lsr #1
178 subhs \dividend, \dividend, \divisor, lsr #1
179 cmp \dividend, \divisor, lsr #2
180 subhs \dividend, \dividend, \divisor, lsr #2
181 cmp \dividend, \divisor, lsr #3
182 subhs \dividend, \dividend, \divisor, lsr #3
183 cmp \dividend, #1
184 mov \divisor, \divisor, lsr #4
185 subges \order, \order, #4
186 bge 1b
187
188 tst \order, #3
189 teqne \dividend, #0
190 beq 5f
191
192 @ Either 1, 2 or 3 comparison/substractions are left.
193 2: cmn \order, #2
194 blt 4f
195 beq 3f
196 cmp \dividend, \divisor
197 subhs \dividend, \dividend, \divisor
198 mov \divisor, \divisor, lsr #1
199 3: cmp \dividend, \divisor
200 subhs \dividend, \dividend, \divisor
201 mov \divisor, \divisor, lsr #1
202 4: cmp \dividend, \divisor
203 subhs \dividend, \dividend, \divisor
204 5:
205 .endm
206
207
208 /*ENTRY(__udivsi3)
209 ENTRY(__aeabi_uidiv)
210
211 subs r2, r1, #1
212 moveq pc, lr
213 bcc Ldiv0
214 cmp r0, r1
215 bls 11f
216 tst r1, r2
217 beq 12f
218
219 ARM_DIV_BODY r0, r1, r2, r3
220
221 mov r0, r2
222 mov pc, lr
223
224 11: moveq r0, #1
225 movne r0, #0
226 mov pc, lr
227
228 12: ARM_DIV2_ORDER r1, r2
229
230 mov r0, r0, lsr r2
231 mov pc, lr
232 */
233
234 ENTRY(__umodsi3)
235
236 0000 012051E2 subs r2, r1, #1 @ compare divisor with 1
237 0004 A700003A bcc Ldiv0
238 0008 01005011 cmpne r0, r1 @ compare dividend with divisor
239 000c 0000A003 moveq r0, #0
240 0010 02001181 tsthi r1, r2 @ see if divisor is power of 2
241 0014 02000000 andeq r0, r0, r2
242 0018 0EF0A091 movls pc, lr
243
244 ARM_MOD_BODY r0, r1, r2, r3
245
246 00b8 0EF0A0E1 mov pc, lr
247
248
249 ENTRY(__divsi3)
250 ENTRY(__aeabi_idiv)
251
252 00bc 000051E3 cmp r1, #0
253 00c0 01C020E0 eor ip, r0, r1 @ save the sign of the result.
254 00c4 7700000A beq Ldiv0
255 00c8 00106142 rsbmi r1, r1, #0 @ loops below use unsigned.
256 00cc 012051E2 subs r2, r1, #1 @ division by 1 or -1 ?
257 00d0 2700000A beq 10f
258 00d4 0030B0E1 movs r3, r0
259 00d8 00306042 rsbmi r3, r0, #0 @ positive dividend value
260 00dc 010053E1 cmp r3, r1
261 00e0 2600009A bls 11f
262 00e4 020011E1 tst r1, r2 @ divisor is power of 2 ?
263 00e8 2800000A beq 12f
264
265 ARM_DIV_BODY r3, r1, r0, r2
266
267 0168 00005CE3 cmp ip, #0
268 016c 00006042 rsbmi r0, r0, #0
269 0170 0EF0A0E1 mov pc, lr
270
271 0174 00003CE1 10: teq ip, r0 @ same sign ?
272 0178 00006042 rsbmi r0, r0, #0
273 017c 0EF0A0E1 mov pc, lr
274
275 0180 0000A033 11: movlo r0, #0
276 0184 CC0FA001 moveq r0, ip, asr #31
277 0188 01008003 orreq r0, r0, #1
278 018c 0EF0A0E1 mov pc, lr
279
280 12: ARM_DIV2_ORDER r1, r2
281
282 01c4 00005CE3 cmp ip, #0
283 01c8 3302A0E1 mov r0, r3, lsr r2
284 01cc 00006042 rsbmi r0, r0, #0
285 01d0 0EF0A0E1 mov pc, lr
286
287
288 ENTRY(__modsi3)
289
290 01d4 000051E3 cmp r1, #0
291 01d8 3200000A beq Ldiv0
292 01dc 00106142 rsbmi r1, r1, #0 @ loops below use unsigned.
293 01e0 00C0B0E1 movs ip, r0 @ preserve sign of dividend
294 01e4 00006042 rsbmi r0, r0, #0 @ if negative make positive
295 01e8 012051E2 subs r2, r1, #1 @ compare divisor with 1
296 01ec 01005011 cmpne r0, r1 @ compare dividend with divisor
297 01f0 0000A003 moveq r0, #0
298 01f4 02001181 tsthi r1, r2 @ see if divisor is power of 2
299 01f8 02000000 andeq r0, r0, r2
300 01fc 2600009A bls 10f
301
302 ARM_MOD_BODY r0, r1, r2, r3
303
304 029c 00005CE3 10: cmp ip, #0
305 02a0 00006042 rsbmi r0, r0, #0
306 02a4 0EF0A0E1 mov pc, lr
307
308 #ifdef CONFIG_AEABI
309
310 ENTRY(__aeabi_uidivmod)
311
312 stmfd sp!, {r0, r1, ip, lr}
313 bl __aeabi_uidiv
314 ldmfd sp!, {r1, r2, ip, lr}
315 mul r3, r0, r2
316 sub r1, r1, r3
317 mov pc, lr
318
319 ENTRY(__aeabi_idivmod)
320
321 stmfd sp!, {r0, r1, ip, lr}
322 bl __aeabi_idiv
323 ldmfd sp!, {r1, r2, ip, lr}
324 mul r3, r0, r2
325 sub r1, r1, r3
326 mov pc, lr
327
328 #endif
329
330 Ldiv0:
331
332 02a8 08E02DE5 str lr, [sp, #-8]!
333 02ac FEFFFFEB bl __div0
334 02b0 0000A0E3 mov r0, #0 @ About as wrong as it could be.
335 02b4 08F09DE4 ldr pc, [sp], #8
336
337 ENTRY(__div0)
338 02b8 0EF0A0E1 mov pc, lr
DEFINED SYMBOLS
lib/lib1funcs.S:234 .text:00000000 __umodsi3
lib/lib1funcs.S:234 .text:00000000 $a
lib/lib1funcs.S:330 .text:000002a8 Ldiv0
lib/lib1funcs.S:249 .text:000000bc __divsi3
lib/lib1funcs.S:250 .text:000000bc __aeabi_idiv
lib/lib1funcs.S:288 .text:000001d4 __modsi3
lib/lib1funcs.S:337 .text:000002b8 __div0
.debug_aranges:0000000c $d
NO UNDEFINED SYMBOLS
+405
View File
@@ -0,0 +1,405 @@
//* ----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//* ----------------------------------------------------------------------------
//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//* ----------------------------------------------------------------------------
//* File Name : lib_AT91SAM7S64.h
//* Object : AT91SAM7S64 inlined functions
//* Generated : AT91 SW Application Group 08/30/2005 (15:52:59)
//*
#include <sys/types.h>
#include <include/AT91SAM7.h>
#include <include/lib_AT91SAM7.h>
//*----------------------------------------------------------------------------
//* \fn AT91F_AIC_ConfigureIt
//* \brief Interrupt Handler Initialization
//*----------------------------------------------------------------------------
unsigned int AT91F_AIC_ConfigureIt (
AT91PS_AIC pAic, // \arg pointer to the AIC registers
unsigned int irq_id, // \arg interrupt number to initialize
unsigned int priority, // \arg priority to give to the interrupt
unsigned int src_type, // \arg activation and sense of activation
void (*newHandler) () ) // \arg address of the interrupt handler
{
unsigned int oldHandler;
unsigned int mask ;
oldHandler = pAic->AIC_SVR[irq_id];
mask = 0x1 << irq_id ;
//* Disable the interrupt on the interrupt controller
pAic->AIC_IDCR = mask ;
//* Save the interrupt handler routine pointer and the interrupt priority
pAic->AIC_SVR[irq_id] = (unsigned int) newHandler ;
//* Store the Source Mode Register
pAic->AIC_SMR[irq_id] = src_type | priority ;
//* Clear the interrupt on the interrupt controller
pAic->AIC_ICCR = mask ;
return oldHandler;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_AIC_SetExceptionVector
//* \brief Configure vector handler
//*----------------------------------------------------------------------------
unsigned int AT91F_AIC_SetExceptionVector (
unsigned int *pVector, // \arg pointer to the AIC registers
void (*Handler) () ) // \arg Interrupt Handler
{
unsigned int oldVector = *pVector;
if ((unsigned int) Handler == (unsigned int) AT91C_AIC_BRANCH_OPCODE)
*pVector = (unsigned int) AT91C_AIC_BRANCH_OPCODE;
else
*pVector = (((((unsigned int) Handler) - ((unsigned int) pVector) - 0x8) >> 2) & 0x00FFFFFF) | 0xEA000000;
return oldVector;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_AIC_Open
//* \brief Set exception vectors and AIC registers to default values
//*----------------------------------------------------------------------------
void AT91F_AIC_Open(
AT91PS_AIC pAic, // \arg pointer to the AIC registers
void (*IrqHandler) (), // \arg Default IRQ vector exception
void (*FiqHandler) (), // \arg Default FIQ vector exception
void (*DefaultHandler) (), // \arg Default Handler set in ISR
void (*SpuriousHandler) (), // \arg Default Spurious Handler
unsigned int protectMode) // \arg Debug Control Register
{
int i;
// Disable all interrupts and set IVR to the default handler
for (i = 0; i < 32; ++i) {
AT91F_AIC_DisableIt(pAic, i);
AT91F_AIC_ConfigureIt(pAic, i, AT91C_AIC_PRIOR_LOWEST, AT91C_AIC_SRCTYPE_HIGH_LEVEL, DefaultHandler);
}
// Set the IRQ exception vector
AT91F_AIC_SetExceptionVector((unsigned int *) 0x18, IrqHandler);
// Set the Fast Interrupt exception vector
AT91F_AIC_SetExceptionVector((unsigned int *) 0x1C, FiqHandler);
pAic->AIC_SPU = (unsigned int) SpuriousHandler;
pAic->AIC_DCR = protectMode;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_PDC_Open
//* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX
//*----------------------------------------------------------------------------
void AT91F_PDC_Open(AT91PS_PDC pPDC) // \arg pointer to a PDC controller
{
//* Disable the RX and TX PDC transfer requests
AT91F_PDC_DisableRx(pPDC);
AT91F_PDC_DisableTx(pPDC);
//* Reset all Counter register Next buffer first
AT91F_PDC_SetNextTx(pPDC, NULL, 0);
AT91F_PDC_SetNextRx(pPDC, NULL, 0);
AT91F_PDC_SetTx(pPDC, NULL, 0);
AT91F_PDC_SetRx(pPDC, NULL, 0);
//* Enable the RX and TX PDC transfer requests
AT91F_PDC_EnableRx(pPDC);
AT91F_PDC_EnableTx(pPDC);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_PDC_Close
//* \brief Close PDC: disable TX and RX reset transfer descriptors
//*----------------------------------------------------------------------------
void AT91F_PDC_Close(AT91PS_PDC pPDC) // \arg pointer to a PDC controller
{
//* Disable the RX and TX PDC transfer requests
AT91F_PDC_DisableRx(pPDC);
AT91F_PDC_DisableTx(pPDC);
//* Reset all Counter register Next buffer first
AT91F_PDC_SetNextTx(pPDC, NULL, 0);
AT91F_PDC_SetNextRx(pPDC, NULL, 0);
AT91F_PDC_SetTx(pPDC, NULL, 0);
AT91F_PDC_SetRx(pPDC, NULL, 0);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_PDC_SendFrame
//* \brief Close PDC: disable TX and RX reset transfer descriptors
//*----------------------------------------------------------------------------
unsigned int AT91F_PDC_SendFrame(
AT91PS_PDC pPDC,
const unsigned char *pBuffer,
unsigned int szBuffer,
const unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
if (AT91F_PDC_IsTxEmpty(pPDC)) {
//* Buffer and next buffer can be initialized
AT91F_PDC_SetTx(pPDC, pBuffer, szBuffer);
AT91F_PDC_SetNextTx(pPDC, pNextBuffer, szNextBuffer);
return 2;
}
else if (AT91F_PDC_IsNextTxEmpty(pPDC)) {
//* Only one buffer can be initialized
AT91F_PDC_SetNextTx(pPDC, pBuffer, szBuffer);
return 1;
}
else {
//* All buffer are in use...
return 0;
}
}
//*----------------------------------------------------------------------------
//* \fn AT91F_PDC_ReceiveFrame
//* \brief Close PDC: disable TX and RX reset transfer descriptors
//*----------------------------------------------------------------------------
unsigned int AT91F_PDC_ReceiveFrame (
AT91PS_PDC pPDC,
unsigned char *pBuffer,
unsigned int szBuffer,
unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
if (AT91F_PDC_IsRxEmpty(pPDC)) {
//* Buffer and next buffer can be initialized
AT91F_PDC_SetRx(pPDC, pBuffer, szBuffer);
AT91F_PDC_SetNextRx(pPDC, pNextBuffer, szNextBuffer);
return 2;
}
else if (AT91F_PDC_IsNextRxEmpty(pPDC)) {
//* Only one buffer can be initialized
AT91F_PDC_SetNextRx(pPDC, pBuffer, szBuffer);
return 1;
}
else {
//* All buffer are in use...
return 0;
}
}
//*------------------------------------------------------------------------------
//* \fn AT91F_PMC_GetMasterClock
//* \brief Return master clock in Hz which correponds to processor clock for ARM7
//*------------------------------------------------------------------------------
unsigned int AT91F_PMC_GetMasterClock (
AT91PS_PMC pPMC, // \arg pointer to PMC controller
AT91PS_CKGR pCKGR, // \arg pointer to CKGR controller
unsigned int slowClock) // \arg slowClock in Hz
{
unsigned int reg = pPMC->PMC_MCKR;
unsigned int prescaler = (1 << ((reg & AT91C_PMC_PRES) >> 2));
unsigned int pllDivider, pllMultiplier;
switch (reg & AT91C_PMC_CSS) {
case AT91C_PMC_CSS_SLOW_CLK: // Slow clock selected
return slowClock / prescaler;
case AT91C_PMC_CSS_MAIN_CLK: // Main clock is selected
return AT91F_CKGR_GetMainClock(pCKGR, slowClock) / prescaler;
case AT91C_PMC_CSS_PLL_CLK: // PLLB clock is selected
reg = pCKGR->CKGR_PLLR;
pllDivider = (reg & AT91C_CKGR_DIV);
pllMultiplier = ((reg & AT91C_CKGR_MUL) >> 16) + 1;
return AT91F_CKGR_GetMainClock(pCKGR, slowClock) / pllDivider * pllMultiplier / prescaler;
}
return 0;
}
//*--------------------------------------------------------------------------------------
//* \fn AT91F_RTT_ReadValue()
//* \brief Read the RTT value
//*--------------------------------------------------------------------------------------
unsigned int AT91F_RTTReadValue(AT91PS_RTTC pRTTC)
{
register volatile unsigned int val1,val2;
do
{
val1 = pRTTC->RTTC_RTVR;
val2 = pRTTC->RTTC_RTVR;
}
while(val1 != val2);
return(val1);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SPI_Close
//* \brief Close SPI: disable IT disable transfert, close PDC
//*----------------------------------------------------------------------------
void AT91F_SPI_Close(AT91PS_SPI pSPI) // \arg pointer to a SPI controller
{
//* Reset all the Chip Select register
pSPI->SPI_CSR[0] = 0 ;
pSPI->SPI_CSR[1] = 0 ;
pSPI->SPI_CSR[2] = 0 ;
pSPI->SPI_CSR[3] = 0 ;
//* Reset the SPI mode
pSPI->SPI_MR = 0 ;
//* Disable all interrupts
pSPI->SPI_IDR = 0xFFFFFFFF ;
//* Abort the Peripheral Data Transfers
AT91F_PDC_Close((AT91PS_PDC) &(pSPI->SPI_RPR));
//* Disable receiver and transmitter and stop any activity immediately
pSPI->SPI_CR = AT91C_SPI_SPIDIS;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_ADC_CfgTimings
//* \brief Configure the different necessary timings of the ADC controller
//*----------------------------------------------------------------------------
void AT91F_ADC_CfgTimings (
AT91PS_ADC pADC, // pointer to a ADC controller
unsigned int mck_clock, // in MHz
unsigned int adc_clock, // in MHz
unsigned int startup_time, // in us
unsigned int sample_and_hold_time) // in ns
{
unsigned int prescal,startup,shtim;
prescal = mck_clock/(2*adc_clock) - 1;
startup = adc_clock*startup_time/8 - 1;
shtim = adc_clock*sample_and_hold_time/1000 - 1;
//* Write to the MR register
pADC->ADC_MR = ( (prescal<<8) & AT91C_ADC_PRESCAL) | ( (startup<<16) & AT91C_ADC_STARTUP) | ( (shtim<<24) & AT91C_ADC_SHTIM);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SSC_SetBaudrate
//* \brief Set the baudrate according to the CPU clock
//*----------------------------------------------------------------------------
void AT91F_SSC_SetBaudrate (
AT91PS_SSC pSSC, // \arg pointer to a SSC controller
unsigned int mainClock, // \arg peripheral clock
unsigned int speed) // \arg SSC baudrate
{
unsigned int baud_value;
//* Define the baud rate divisor register
if (speed == 0)
baud_value = 0;
else
{
baud_value = (unsigned int) (mainClock * 10)/(2*speed);
if ((baud_value % 10) >= 5)
baud_value = (baud_value / 10) + 1;
else
baud_value /= 10;
}
pSSC->SSC_CMR = baud_value;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_SSC_Configure
//* \brief Configure SSC
//*----------------------------------------------------------------------------
void AT91F_SSC_Configure (
AT91PS_SSC pSSC, // \arg pointer to a SSC controller
unsigned int syst_clock, // \arg System Clock Frequency
unsigned int baud_rate, // \arg Expected Baud Rate Frequency
unsigned int clock_rx, // \arg Receiver Clock Parameters
unsigned int mode_rx, // \arg mode Register to be programmed
unsigned int clock_tx, // \arg Transmitter Clock Parameters
unsigned int mode_tx) // \arg mode Register to be programmed
{
//* Disable interrupts
pSSC->SSC_IDR = (unsigned int) -1;
//* Reset receiver and transmitter
pSSC->SSC_CR = AT91C_SSC_SWRST | AT91C_SSC_RXDIS | AT91C_SSC_TXDIS ;
//* Define the Clock Mode Register
AT91F_SSC_SetBaudrate(pSSC, syst_clock, baud_rate);
//* Write the Receive Clock Mode Register
pSSC->SSC_RCMR = clock_rx;
//* Write the Transmit Clock Mode Register
pSSC->SSC_TCMR = clock_tx;
//* Write the Receive Frame Mode Register
pSSC->SSC_RFMR = mode_rx;
//* Write the Transmit Frame Mode Register
pSSC->SSC_TFMR = mode_tx;
//* Clear Transmit and Receive Counters
AT91F_PDC_Open((AT91PS_PDC) &(pSSC->SSC_RPR));
}
//*----------------------------------------------------------------------------
//* \fn AT91F_US_Configure
//* \brief Configure USART
//*----------------------------------------------------------------------------
void AT91F_US_Configure (
AT91PS_USART pUSART, // \arg pointer to a USART controller
unsigned int mainClock, // \arg peripheral clock
unsigned int mode , // \arg mode Register to be programmed
unsigned int baudRate , // \arg baudrate to be programmed
unsigned int timeguard ) // \arg timeguard to be programmed
{
//* Disable interrupts
pUSART->US_IDR = (unsigned int) -1;
//* Reset receiver and transmitter
pUSART->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS ;
//* Define the baud rate divisor register
AT91F_US_SetBaudrate(pUSART, mainClock, baudRate);
//* Write the Timeguard Register
AT91F_US_SetTimeguard(pUSART, timeguard);
//* Clear Transmit and Receive Counters
AT91F_PDC_Open((AT91PS_PDC) &(pUSART->US_RPR));
//* Define the USART mode
pUSART->US_MR = mode ;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_US_Close
//* \brief Close USART: disable IT disable receiver and transmitter, close PDC
//*----------------------------------------------------------------------------
void AT91F_US_Close(AT91PS_USART pUSART) // \arg pointer to a USART controller
{
//* Reset the baud rate divisor register
pUSART->US_BRGR = 0 ;
//* Reset the USART mode
pUSART->US_MR = 0 ;
//* Reset the Timeguard Register
pUSART->US_TTGR = 0;
//* Disable all interrupts
pUSART->US_IDR = 0xFFFFFFFF ;
//* Abort the Peripheral Data Transfers
AT91F_PDC_Close((AT91PS_PDC) &(pUSART->US_RPR));
//* Disable receiver and transmitter and stop any activity immediately
pUSART->US_CR = AT91C_US_TXDIS | AT91C_US_RXDIS | AT91C_US_RSTTX | AT91C_US_RSTRX ;
}
File diff suppressed because it is too large Load Diff
+59
View File
@@ -0,0 +1,59 @@
/*
* linux/arch/arm/lib/memcpy.S
*
* Author: Nicolas Pitre
* Created: Sep 28, 2005
* Copyright: MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
.macro ldr1w ptr reg abort
ldr \reg, [\ptr], #4
.endm
.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
.endm
.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
.macro ldr1b ptr reg cond=al abort
ldr\cond\()b \reg, [\ptr], #1
.endm
.macro str1w ptr reg abort
str \reg, [\ptr], #4
.endm
.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
.macro str1b ptr reg cond=al abort
str\cond\()b \reg, [\ptr], #1
.endm
.macro enter reg1 reg2
stmdb sp!, {r0, \reg1, \reg2}
.endm
.macro exit reg1 reg2
ldmfd sp!, {r0, \reg1, \reg2}
.endm
.text
/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
ENTRY(memcpy)
#include "copy_template.S"
+80
View File
@@ -0,0 +1,80 @@
/*
* linux/arch/arm/lib/memset.S
*
* Copyright (C) 1995-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* ASM optimised string functions
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
.text
.align 5
.word 0
1: subs r2, r2, #4 @ 1 do we have enough
blt 5f @ 1 bytes to align with?
cmp r3, #2 @ 1
strltb r1, [r0], #1 @ 1
strleb r1, [r0], #1 @ 1
strb r1, [r0], #1 @ 1
add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
/*
* The pointer is now aligned and the length is adjusted. Try doing the
* memzero again.
*/
ENTRY(memset)
ands r3, r0, #3 @ 1 unaligned?
bne 1b @ 1
/*
* we know that the pointer in r0 is aligned to a word boundary.
*/
orr r1, r1, r1, lsl #8
orr r1, r1, r1, lsl #16
mov r3, r1
cmp r2, #16
blt 4f
/*
* We need an extra register for this loop - save the return address and
* use the LR
*/
str lr, [sp, #-4]!
mov ip, r1
mov lr, r1
2: subs r2, r2, #64
stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
stmgeia r0!, {r1, r3, ip, lr}
stmgeia r0!, {r1, r3, ip, lr}
stmgeia r0!, {r1, r3, ip, lr}
bgt 2b
LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go.
/*
* No need to correct the count; we're only testing bits from now on
*/
tst r2, #32
stmneia r0!, {r1, r3, ip, lr}
stmneia r0!, {r1, r3, ip, lr}
tst r2, #16
stmneia r0!, {r1, r3, ip, lr}
ldr lr, [sp], #4
4: tst r2, #8
stmneia r0!, {r1, r3}
tst r2, #4
strne r1, [r0], #4
/*
* When we get here, we've got less than 4 bytes to zero. We
* may have an unaligned pointer as well.
*/
5: tst r2, #2
strneb r1, [r0], #1
strneb r1, [r0], #1
tst r2, #1
strneb r1, [r0], #1
RETINSTR(mov,pc,lr)
+22
View File
@@ -0,0 +1,22 @@
/*
* linux/arch/arm/lib/setbit.S
*
* Copyright (C) 1995-1996 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
#include "bitops.h"
.text
/*
* Purpose : Function to set a bit
* Prototype: int set_bit(int bit, void *addr)
*/
ENTRY(_set_bit_be)
eor r0, r0, #0x18 @ big endian byte ordering
ENTRY(_set_bit_le)
bitop orr
+170
View File
@@ -0,0 +1,170 @@
1 # 1 "lib/setbit.S"
1 /*
0
0
2 * linux/arch/arm/lib/setbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
11 #include <asm/assembler.h>
1 /*
2 * linux/include/asm-arm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16 #ifndef __ASSEMBLY__
17 #error "Only include this from assembly code"
18 #endif
19
20 #include <asm/ptrace.h>
1 /*
21
22 #define pull lsl
23 #define push lsr
24 #define get_byte_0 lsr #24
25 #define get_byte_1 lsr #16
26 #define get_byte_2 lsr #8
27 #define get_byte_3 lsl #0
28 #define put_byte_0 lsl #24
29 #define put_byte_1 lsl #16
30 #define put_byte_2 lsl #8
31 #define put_byte_3 lsl #0
32
33 #define PLD(code...)
34
35 #define MODE_USR USR_MODE
36 #define MODE_FIQ FIQ_MODE
37 #define MODE_IRQ IRQ_MODE
38 #define MODE_SVC SVC_MODE
39
40 #define DEFAULT_FIQ MODE_FIQ
41
42 /*
43 * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
44 */
45 #ifdef __STDC__
46 #define LOADREGS(cond, base, reglist...)\
47 ldm##cond base,reglist
48 #else
49 #define LOADREGS(cond, base, reglist...)\
50 ldm/**/cond base,reglist
51 #endif
52
53 /*
54 * Build a return instruction for this processor type.
55 */
56 #define RETINSTR(instr, regs...)\
57 instr regs
58
59 /*
60 * Enable and disable interrupts
61 */
62 .macro disable_irq
63 msr cpsr_c, #PSR_I_BIT | SVC_MODE
64 .endm
65
66 .macro enable_irq
67 msr cpsr_c, #SVC_MODE
68 .endm
69
70 /*
71 * Save the current IRQ state and disable IRQs. Note that this macro
72 * assumes FIQs are enabled, and that the processor is in SVC mode.
73 */
74 .macro save_and_disable_irqs, oldcpsr
75 mrs \oldcpsr, cpsr
76 disable_irq
77 .endm
78
79 /*
80 * Restore interrupt state previously stored in a register. We don't
81 * guarantee that this will preserve the flags.
82 */
83 .macro restore_irqs, oldcpsr
84 msr cpsr_c, \oldcpsr
85 .endm
86
87 /*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we do. On 32-bit
90 * architecture, we can safely ignore this requirement.
91 */
92 .macro save_lr
93 .endm
94
95 .macro restore_pc
96 mov pc, lr
97 .endm
98 ...
12 #include "bitops.h"
1 .macro bitop, instr
2 and r2, r0, #7
3 mov r3, #1
4 mov r3, r3, lsl r2
5 save_and_disable_irqs ip
6 ldrb r2, [r1, r0, lsr #3]
7 \instr r2, r2, r3
8 strb r2, [r1, r0, lsr #3]
9 restore_irqs ip
10 mov pc, lr
11 .endm
12
13 /**
14 * testop - implement a test_and_xxx_bit operation.
15 * @instr: operational instruction
16 * @store: store instruction
17 *
18 * Note: we can trivially conditionalise the store instruction
19 * to avoid dirting the data cache.
20 */
21 .macro testop, instr, store
22 add r1, r1, r0, lsr #3
23 and r3, r0, #7
24 mov r0, #1
25 save_and_disable_irqs ip
26 ldrb r2, [r1]
27 tst r2, r0, lsl r3
28 \instr r2, r2, r0, lsl r3
29 \store r2, [r1]
30 restore_irqs ip
31 moveq r0, #0
32 mov pc, lr
33 .endm
34 ...
13 .text
14
15 /*
16 * Purpose : Function to set a bit
17 * Prototype: int set_bit(int bit, void *addr)
18 */
19 ENTRY(_set_bit_be)
20 0000 180020E2 eor r0, r0, #0x18 @ big endian byte ordering
21 ENTRY(_set_bit_le)
22 0004 072000E2 bitop orr
22 0130A0E3
22 1332A0E1
22 00C00FE1
22 93F021E3
DEFINED SYMBOLS
lib/setbit.S:19 .text:00000000 _set_bit_be
lib/setbit.S:19 .text:00000000 $a
lib/setbit.S:21 .text:00000004 _set_bit_le
.debug_aranges:0000000c $d
NO UNDEFINED SYMBOLS
+41
View File
@@ -0,0 +1,41 @@
/*
* linux/lib/string.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
* stupid library routines.. The optimized versions should generally be found
* as inline code in <asm-xx/string.h>
*
* These are buggy as well..
*
* * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
* - Added strsep() which will replace strtok() soon (because strsep() is
* reentrant and should be faster). Use only strsep() in new code, please.
*
* * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
* Matthew Hawkins <matt@mh.dropbear.id.au>
* - Kissed strtok() goodbye
*/
#include <sys/types.h>
#include <string.h>
#include <asm/ctype.h>
#ifndef __HAVE_ARCH_STRNLEN
/**
* strnlen - Find the length of a length-limited string
* @s: The string to be sized
* @count: The maximum number of bytes to search
*/
size_t strnlen(const char *s, size_t count)
{
const char *sc;
for (sc = s; count-- && *sc != '\0'; ++sc)
/* nothing */;
return sc - s;
}
#endif
+94
View File
@@ -0,0 +1,94 @@
1 .cpu arm7tdmi
2 .fpu softvfp
3 .eabi_attribute 20, 1
4 .eabi_attribute 21, 1
5 .eabi_attribute 23, 3
6 .eabi_attribute 24, 1
7 .eabi_attribute 25, 1
8 .eabi_attribute 26, 1
9 .eabi_attribute 30, 4
10 .eabi_attribute 18, 4
11 .file "string.c"
19 .Ltext0:
20 .cfi_sections .debug_frame
21 .align 2
22 .global strnlen
24 strnlen:
25 .LFB2:
26 .file 1 "lib/string.c"
1:lib/string.c **** /*
2:lib/string.c **** * linux/lib/string.c
3:lib/string.c **** *
4:lib/string.c **** * Copyright (C) 1991, 1992 Linus Torvalds
5:lib/string.c **** */
6:lib/string.c ****
7:lib/string.c **** /*
8:lib/string.c **** * stupid library routines.. The optimized versions should generally be found
9:lib/string.c **** * as inline code in <asm-xx/string.h>
10:lib/string.c **** *
11:lib/string.c **** * These are buggy as well..
12:lib/string.c **** *
13:lib/string.c **** * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
14:lib/string.c **** * - Added strsep() which will replace strtok() soon (because strsep() is
15:lib/string.c **** * reentrant and should be faster). Use only strsep() in new code, please.
16:lib/string.c **** *
17:lib/string.c **** * * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
18:lib/string.c **** * Matthew Hawkins <matt@mh.dropbear.id.au>
19:lib/string.c **** * - Kissed strtok() goodbye
20:lib/string.c **** */
21:lib/string.c ****
22:lib/string.c **** #include <sys/types.h>
23:lib/string.c **** #include <string.h>
24:lib/string.c **** #include <asm/ctype.h>
25:lib/string.c ****
26:lib/string.c ****
27:lib/string.c **** #ifndef __HAVE_ARCH_STRNLEN
28:lib/string.c **** /**
29:lib/string.c **** * strnlen - Find the length of a length-limited string
30:lib/string.c **** * @s: The string to be sized
31:lib/string.c **** * @count: The maximum number of bytes to search
32:lib/string.c **** */
33:lib/string.c **** size_t strnlen(const char *s, size_t count)
34:lib/string.c **** {
27 .loc 1 34 0
28 .cfi_startproc
29 @ Function supports interworking.
30 @ args = 0, pretend = 0, frame = 0
31 @ frame_needed = 0, uses_anonymous_args = 0
32 @ link register save eliminated.
33 .LVL0:
34 .loc 1 34 0
35 0000 0030A0E1 mov r3, r0
36 .LVL1:
37 .L3:
35:lib/string.c **** const char *sc;
36:lib/string.c ****
37:lib/string.c **** for (sc = s; count-- && *sc != '\0'; ++sc)
38 .loc 1 37 0 discriminator 1
39 0004 011051E2 subs r1, r1, #1
40 0008 0320A0E1 mov r2, r3
41 .LVL2:
42 000c 0200003A bcc .L2
43 .loc 1 37 0 is_stmt 0 discriminator 2
44 0010 01C0D3E4 ldrb ip, [r3], #1 @ zero_extendqisi2
45 .LVL3:
46 0014 00005CE3 cmp ip, #0
47 0018 F9FFFF1A bne .L3
48 .L2:
38:lib/string.c **** /* nothing */;
39:lib/string.c **** return sc - s;
40:lib/string.c **** }
49 .loc 1 40 0 is_stmt 1
50 001c 020060E0 rsb r0, r0, r2
51 .LVL4:
52 0020 1EFF2FE1 bx lr
53 .cfi_endproc
54 .LFE2:
56 .Letext0:
DEFINED SYMBOLS
*ABS*:00000000 string.c
C:\Users\netz\AppData\Local\Temp\cc4Ne3c1.s:21 .text:00000000 $a
C:\Users\netz\AppData\Local\Temp\cc4Ne3c1.s:24 .text:00000000 strnlen
.debug_frame:00000010 $d
NO UNDEFINED SYMBOLS
+18
View File
@@ -0,0 +1,18 @@
/*
* linux/arch/arm/lib/testchangebit.S
*
* Copyright (C) 1995-1996 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
#include "bitops.h"
.text
ENTRY(_test_and_change_bit_be)
eor r0, r0, #0x18 @ big endian byte ordering
ENTRY(_test_and_change_bit_le)
testop eor, strb
+166
View File
@@ -0,0 +1,166 @@
1 # 1 "lib/testchangebit.S"
1 /*
0
0
2 * linux/arch/arm/lib/testchangebit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
11 #include <asm/assembler.h>
1 /*
2 * linux/include/asm-arm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16 #ifndef __ASSEMBLY__
17 #error "Only include this from assembly code"
18 #endif
19
20 #include <asm/ptrace.h>
1 /*
21
22 #define pull lsl
23 #define push lsr
24 #define get_byte_0 lsr #24
25 #define get_byte_1 lsr #16
26 #define get_byte_2 lsr #8
27 #define get_byte_3 lsl #0
28 #define put_byte_0 lsl #24
29 #define put_byte_1 lsl #16
30 #define put_byte_2 lsl #8
31 #define put_byte_3 lsl #0
32
33 #define PLD(code...)
34
35 #define MODE_USR USR_MODE
36 #define MODE_FIQ FIQ_MODE
37 #define MODE_IRQ IRQ_MODE
38 #define MODE_SVC SVC_MODE
39
40 #define DEFAULT_FIQ MODE_FIQ
41
42 /*
43 * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
44 */
45 #ifdef __STDC__
46 #define LOADREGS(cond, base, reglist...)\
47 ldm##cond base,reglist
48 #else
49 #define LOADREGS(cond, base, reglist...)\
50 ldm/**/cond base,reglist
51 #endif
52
53 /*
54 * Build a return instruction for this processor type.
55 */
56 #define RETINSTR(instr, regs...)\
57 instr regs
58
59 /*
60 * Enable and disable interrupts
61 */
62 .macro disable_irq
63 msr cpsr_c, #PSR_I_BIT | SVC_MODE
64 .endm
65
66 .macro enable_irq
67 msr cpsr_c, #SVC_MODE
68 .endm
69
70 /*
71 * Save the current IRQ state and disable IRQs. Note that this macro
72 * assumes FIQs are enabled, and that the processor is in SVC mode.
73 */
74 .macro save_and_disable_irqs, oldcpsr
75 mrs \oldcpsr, cpsr
76 disable_irq
77 .endm
78
79 /*
80 * Restore interrupt state previously stored in a register. We don't
81 * guarantee that this will preserve the flags.
82 */
83 .macro restore_irqs, oldcpsr
84 msr cpsr_c, \oldcpsr
85 .endm
86
87 /*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we do. On 32-bit
90 * architecture, we can safely ignore this requirement.
91 */
92 .macro save_lr
93 .endm
94
95 .macro restore_pc
96 mov pc, lr
97 .endm
98 ...
12 #include "bitops.h"
1 .macro bitop, instr
2 and r2, r0, #7
3 mov r3, #1
4 mov r3, r3, lsl r2
5 save_and_disable_irqs ip
6 ldrb r2, [r1, r0, lsr #3]
7 \instr r2, r2, r3
8 strb r2, [r1, r0, lsr #3]
9 restore_irqs ip
10 mov pc, lr
11 .endm
12
13 /**
14 * testop - implement a test_and_xxx_bit operation.
15 * @instr: operational instruction
16 * @store: store instruction
17 *
18 * Note: we can trivially conditionalise the store instruction
19 * to avoid dirting the data cache.
20 */
21 .macro testop, instr, store
22 add r1, r1, r0, lsr #3
23 and r3, r0, #7
24 mov r0, #1
25 save_and_disable_irqs ip
26 ldrb r2, [r1]
27 tst r2, r0, lsl r3
28 \instr r2, r2, r0, lsl r3
29 \store r2, [r1]
30 restore_irqs ip
31 moveq r0, #0
32 mov pc, lr
33 .endm
34 ...
13 .text
14
15 ENTRY(_test_and_change_bit_be)
16 0000 180020E2 eor r0, r0, #0x18 @ big endian byte ordering
17 ENTRY(_test_and_change_bit_le)
18 0004 A01181E0 testop eor, strb
18 073000E2
18 0100A0E3
18 00C00FE1
18 93F021E3
DEFINED SYMBOLS
lib/testchangebit.S:15 .text:00000000 _test_and_change_bit_be
lib/testchangebit.S:15 .text:00000000 $a
lib/testchangebit.S:17 .text:00000004 _test_and_change_bit_le
.debug_aranges:0000000c $d
NO UNDEFINED SYMBOLS
+18
View File
@@ -0,0 +1,18 @@
/*
* linux/arch/arm/lib/testclearbit.S
*
* Copyright (C) 1995-1996 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
#include "bitops.h"
.text
ENTRY(_test_and_clear_bit_be)
eor r0, r0, #0x18 @ big endian byte ordering
ENTRY(_test_and_clear_bit_le)
testop bicne, strneb
+166
View File
@@ -0,0 +1,166 @@
1 # 1 "lib/testclearbit.S"
1 /*
0
0
2 * linux/arch/arm/lib/testclearbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
11 #include <asm/assembler.h>
1 /*
2 * linux/include/asm-arm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16 #ifndef __ASSEMBLY__
17 #error "Only include this from assembly code"
18 #endif
19
20 #include <asm/ptrace.h>
1 /*
21
22 #define pull lsl
23 #define push lsr
24 #define get_byte_0 lsr #24
25 #define get_byte_1 lsr #16
26 #define get_byte_2 lsr #8
27 #define get_byte_3 lsl #0
28 #define put_byte_0 lsl #24
29 #define put_byte_1 lsl #16
30 #define put_byte_2 lsl #8
31 #define put_byte_3 lsl #0
32
33 #define PLD(code...)
34
35 #define MODE_USR USR_MODE
36 #define MODE_FIQ FIQ_MODE
37 #define MODE_IRQ IRQ_MODE
38 #define MODE_SVC SVC_MODE
39
40 #define DEFAULT_FIQ MODE_FIQ
41
42 /*
43 * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
44 */
45 #ifdef __STDC__
46 #define LOADREGS(cond, base, reglist...)\
47 ldm##cond base,reglist
48 #else
49 #define LOADREGS(cond, base, reglist...)\
50 ldm/**/cond base,reglist
51 #endif
52
53 /*
54 * Build a return instruction for this processor type.
55 */
56 #define RETINSTR(instr, regs...)\
57 instr regs
58
59 /*
60 * Enable and disable interrupts
61 */
62 .macro disable_irq
63 msr cpsr_c, #PSR_I_BIT | SVC_MODE
64 .endm
65
66 .macro enable_irq
67 msr cpsr_c, #SVC_MODE
68 .endm
69
70 /*
71 * Save the current IRQ state and disable IRQs. Note that this macro
72 * assumes FIQs are enabled, and that the processor is in SVC mode.
73 */
74 .macro save_and_disable_irqs, oldcpsr
75 mrs \oldcpsr, cpsr
76 disable_irq
77 .endm
78
79 /*
80 * Restore interrupt state previously stored in a register. We don't
81 * guarantee that this will preserve the flags.
82 */
83 .macro restore_irqs, oldcpsr
84 msr cpsr_c, \oldcpsr
85 .endm
86
87 /*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we do. On 32-bit
90 * architecture, we can safely ignore this requirement.
91 */
92 .macro save_lr
93 .endm
94
95 .macro restore_pc
96 mov pc, lr
97 .endm
98 ...
12 #include "bitops.h"
1 .macro bitop, instr
2 and r2, r0, #7
3 mov r3, #1
4 mov r3, r3, lsl r2
5 save_and_disable_irqs ip
6 ldrb r2, [r1, r0, lsr #3]
7 \instr r2, r2, r3
8 strb r2, [r1, r0, lsr #3]
9 restore_irqs ip
10 mov pc, lr
11 .endm
12
13 /**
14 * testop - implement a test_and_xxx_bit operation.
15 * @instr: operational instruction
16 * @store: store instruction
17 *
18 * Note: we can trivially conditionalise the store instruction
19 * to avoid dirting the data cache.
20 */
21 .macro testop, instr, store
22 add r1, r1, r0, lsr #3
23 and r3, r0, #7
24 mov r0, #1
25 save_and_disable_irqs ip
26 ldrb r2, [r1]
27 tst r2, r0, lsl r3
28 \instr r2, r2, r0, lsl r3
29 \store r2, [r1]
30 restore_irqs ip
31 moveq r0, #0
32 mov pc, lr
33 .endm
34 ...
13 .text
14
15 ENTRY(_test_and_clear_bit_be)
16 0000 180020E2 eor r0, r0, #0x18 @ big endian byte ordering
17 ENTRY(_test_and_clear_bit_le)
18 0004 A01181E0 testop bicne, strneb
18 073000E2
18 0100A0E3
18 00C00FE1
18 93F021E3
DEFINED SYMBOLS
lib/testclearbit.S:15 .text:00000000 _test_and_clear_bit_be
lib/testclearbit.S:15 .text:00000000 $a
lib/testclearbit.S:17 .text:00000004 _test_and_clear_bit_le
.debug_aranges:0000000c $d
NO UNDEFINED SYMBOLS
+18
View File
@@ -0,0 +1,18 @@
/*
* linux/arch/arm/lib/testsetbit.S
*
* Copyright (C) 1995-1996 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/linkage.h>
#include <asm/assembler.h>
#include "bitops.h"
.text
ENTRY(_test_and_set_bit_be)
eor r0, r0, #0x18 @ big endian byte ordering
ENTRY(_test_and_set_bit_le)
testop orreq, streqb
+166
View File
@@ -0,0 +1,166 @@
1 # 1 "lib/testsetbit.S"
1 /*
0
0
2 * linux/arch/arm/lib/testsetbit.S
3 *
4 * Copyright (C) 1995-1996 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 #include <asm/linkage.h>
1 #ifndef __ASM_LINKAGE_H
11 #include <asm/assembler.h>
1 /*
2 * linux/include/asm-arm/assembler.h
3 *
4 * Copyright (C) 1996-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This file contains arm architecture specific defines
11 * for the different processors.
12 *
13 * Do not include any C declarations in this file - it is included by
14 * assembler source.
15 */
16 #ifndef __ASSEMBLY__
17 #error "Only include this from assembly code"
18 #endif
19
20 #include <asm/ptrace.h>
1 /*
21
22 #define pull lsl
23 #define push lsr
24 #define get_byte_0 lsr #24
25 #define get_byte_1 lsr #16
26 #define get_byte_2 lsr #8
27 #define get_byte_3 lsl #0
28 #define put_byte_0 lsl #24
29 #define put_byte_1 lsl #16
30 #define put_byte_2 lsl #8
31 #define put_byte_3 lsl #0
32
33 #define PLD(code...)
34
35 #define MODE_USR USR_MODE
36 #define MODE_FIQ FIQ_MODE
37 #define MODE_IRQ IRQ_MODE
38 #define MODE_SVC SVC_MODE
39
40 #define DEFAULT_FIQ MODE_FIQ
41
42 /*
43 * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
44 */
45 #ifdef __STDC__
46 #define LOADREGS(cond, base, reglist...)\
47 ldm##cond base,reglist
48 #else
49 #define LOADREGS(cond, base, reglist...)\
50 ldm/**/cond base,reglist
51 #endif
52
53 /*
54 * Build a return instruction for this processor type.
55 */
56 #define RETINSTR(instr, regs...)\
57 instr regs
58
59 /*
60 * Enable and disable interrupts
61 */
62 .macro disable_irq
63 msr cpsr_c, #PSR_I_BIT | SVC_MODE
64 .endm
65
66 .macro enable_irq
67 msr cpsr_c, #SVC_MODE
68 .endm
69
70 /*
71 * Save the current IRQ state and disable IRQs. Note that this macro
72 * assumes FIQs are enabled, and that the processor is in SVC mode.
73 */
74 .macro save_and_disable_irqs, oldcpsr
75 mrs \oldcpsr, cpsr
76 disable_irq
77 .endm
78
79 /*
80 * Restore interrupt state previously stored in a register. We don't
81 * guarantee that this will preserve the flags.
82 */
83 .macro restore_irqs, oldcpsr
84 msr cpsr_c, \oldcpsr
85 .endm
86
87 /*
88 * These two are used to save LR/restore PC over a user-based access.
89 * The old 26-bit architecture requires that we do. On 32-bit
90 * architecture, we can safely ignore this requirement.
91 */
92 .macro save_lr
93 .endm
94
95 .macro restore_pc
96 mov pc, lr
97 .endm
98 ...
12 #include "bitops.h"
1 .macro bitop, instr
2 and r2, r0, #7
3 mov r3, #1
4 mov r3, r3, lsl r2
5 save_and_disable_irqs ip
6 ldrb r2, [r1, r0, lsr #3]
7 \instr r2, r2, r3
8 strb r2, [r1, r0, lsr #3]
9 restore_irqs ip
10 mov pc, lr
11 .endm
12
13 /**
14 * testop - implement a test_and_xxx_bit operation.
15 * @instr: operational instruction
16 * @store: store instruction
17 *
18 * Note: we can trivially conditionalise the store instruction
19 * to avoid dirting the data cache.
20 */
21 .macro testop, instr, store
22 add r1, r1, r0, lsr #3
23 and r3, r0, #7
24 mov r0, #1
25 save_and_disable_irqs ip
26 ldrb r2, [r1]
27 tst r2, r0, lsl r3
28 \instr r2, r2, r0, lsl r3
29 \store r2, [r1]
30 restore_irqs ip
31 moveq r0, #0
32 mov pc, lr
33 .endm
34 ...
13 .text
14
15 ENTRY(_test_and_set_bit_be)
16 0000 180020E2 eor r0, r0, #0x18 @ big endian byte ordering
17 ENTRY(_test_and_set_bit_le)
18 0004 A01181E0 testop orreq, streqb
18 073000E2
18 0100A0E3
18 00C00FE1
18 93F021E3
DEFINED SYMBOLS
lib/testsetbit.S:15 .text:00000000 _test_and_set_bit_be
lib/testsetbit.S:15 .text:00000000 $a
lib/testsetbit.S:17 .text:00000004 _test_and_set_bit_le
.debug_aranges:0000000c $d
NO UNDEFINED SYMBOLS
+831
View File
@@ -0,0 +1,831 @@
/*
* linux/lib/vsprintf.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
/*
* Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
* - changed to provide snprintf and vsnprintf functions
* So Feb 1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
* - scnprintf and vscnprintf
*/
#include <stdarg.h>
#include <sys/types.h>
#include <string.h>
#include <asm/ctype.h>
#include <asm/div64.h>
#include <limits.h>
/**
* simple_strtoul - convert a string to an unsigned long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
{
unsigned long result = 0,value;
if (!base) {
base = 10;
if (*cp == '0') {
base = 8;
cp++;
if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
cp++;
base = 16;
}
}
} else if (base == 16) {
if (cp[0] == '0' && toupper(cp[1]) == 'X')
cp += 2;
}
while (isxdigit(*cp) &&
(value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
result = result*base + value;
cp++;
}
if (endp)
*endp = (char *)cp;
return result;
}
/**
* simple_strtol - convert a string to a signed long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
long simple_strtol(const char *cp,char **endp,unsigned int base)
{
if(*cp=='-')
return -simple_strtoul(cp+1,endp,base);
return simple_strtoul(cp,endp,base);
}
/**
* simple_strtoull - convert a string to an unsigned long long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
{
unsigned long long result = 0,value;
if (!base) {
base = 10;
if (*cp == '0') {
base = 8;
cp++;
if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
cp++;
base = 16;
}
}
} else if (base == 16) {
if (cp[0] == '0' && toupper(cp[1]) == 'X')
cp += 2;
}
while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
? toupper(*cp) : *cp)-'A'+10) < base) {
result = result*base + value;
cp++;
}
if (endp)
*endp = (char *)cp;
return result;
}
/**
* simple_strtoll - convert a string to a signed long long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
long long simple_strtoll(const char *cp,char **endp,unsigned int base)
{
if(*cp=='-')
return -simple_strtoull(cp+1,endp,base);
return simple_strtoull(cp,endp,base);
}
static int skip_atoi(const char **s)
{
int i=0;
while (isdigit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
static char * number(char * buf, char * end, unsigned long long num, int base, int size, int precision, int type)
{
char c,sign,tmp[66];
const char *digits;
static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i;
digits = (type & LARGE) ? large_digits : small_digits;
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return NULL;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if ((signed long long) num < 0) {
sign = '-';
num = - (signed long long) num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
tmp[i++]='0';
else while (num != 0)
tmp[i++] = digits[do_div(num,base)];
if (i > precision)
precision = i;
size -= precision;
if (!(type&(ZEROPAD+LEFT))) {
while(size-->0) {
if (buf <= end)
*buf = ' ';
++buf;
}
}
if (sign) {
if (buf <= end)
*buf = sign;
++buf;
}
if (type & SPECIAL) {
if (base==8) {
if (buf <= end)
*buf = '0';
++buf;
} else if (base==16) {
if (buf <= end)
*buf = '0';
++buf;
if (buf <= end)
*buf = digits[33];
++buf;
}
}
if (!(type & LEFT)) {
while (size-- > 0) {
if (buf <= end)
*buf = c;
++buf;
}
}
while (i < precision--) {
if (buf <= end)
*buf = '0';
++buf;
}
while (i-- > 0) {
if (buf <= end)
*buf = tmp[i];
++buf;
}
while (size-- > 0) {
if (buf <= end)
*buf = ' ';
++buf;
}
return buf;
}
/**
* vsnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @args: Arguments for the format string
*
* The return value is the number of characters which would
* be generated for the given input, excluding the trailing
* '\0', as per ISO C99. If you want to have the exact
* number of characters written into @buf as return value
* (not including the trailing '\0'), use vscnprintf. If the
* return is greater than or equal to @size, the resulting
* string is truncated.
*
* Call this function if you are already dealing with a va_list.
* You probably want snprintf instead.
*/
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
int len;
unsigned long long num;
int i, base;
char *str, *end, c;
const char *s;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
/* 'z' support added 23/7/1999 S.H. */
/* 'z' changed to 'Z' --davidm 1/25/99 */
/* 't' added for ptrdiff_t */
/* Reject out-of-range values early */
if ((int) size < 0) {
return 0;
}
str = buf;
end = buf + size - 1;
if (end < buf - 1) {
end = ((void *) -1);
size = end - buf + 1;
}
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
if (str <= end)
*str = *fmt;
++str;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if (isdigit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if (isdigit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
*fmt =='Z' || *fmt == 'z' || *fmt == 't') {
qualifier = *fmt;
++fmt;
if (qualifier == 'l' && *fmt == 'l') {
qualifier = 'L';
++fmt;
}
}
/* default base */
base = 10;
switch (*fmt) {
case 'c':
if (!(flags & LEFT)) {
while (--field_width > 0) {
if (str <= end)
*str = ' ';
++str;
}
}
c = (unsigned char) va_arg(args, int);
if (str <= end)
*str = c;
++str;
while (--field_width > 0) {
if (str <= end)
*str = ' ';
++str;
}
continue;
case 's':
s = va_arg(args, char *);
len = strnlen(s, precision);
if (!(flags & LEFT)) {
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
}
for (i = 0; i < len; ++i) {
if (str <= end)
*str = *s;
++str; ++s;
}
while (len < field_width--) {
if (str <= end)
*str = ' ';
++str;
}
continue;
case 'p':
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
str = number(str, end,
(unsigned long) va_arg(args, void *),
16, field_width, precision, flags);
continue;
case 'n':
/* FIXME:
* What does C99 say about the overflow case here? */
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
*ip = (str - buf);
} else if (qualifier == 'Z' || qualifier == 'z') {
size_t * ip = va_arg(args, size_t *);
*ip = (str - buf);
} else {
int * ip = va_arg(args, int *);
*ip = (str - buf);
}
continue;
case '%':
if (str <= end)
*str = '%';
++str;
continue;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'X':
flags |= LARGE;
case 'x':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
if (str <= end)
*str = '%';
++str;
if (*fmt) {
if (str <= end)
*str = *fmt;
++str;
} else {
--fmt;
}
continue;
}
if (qualifier == 'L')
num = va_arg(args, long long);
else if (qualifier == 'l') {
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
} else if (qualifier == 'Z' || qualifier == 'z') {
num = va_arg(args, size_t);
} else if (qualifier == 't') {
num = va_arg(args, ptrdiff_t);
} else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = (signed short) num;
} else {
num = va_arg(args, unsigned int);
if (flags & SIGN)
num = (signed int) num;
}
str = number(str, end, num, base,
field_width, precision, flags);
}
if (str <= end)
*str = '\0';
else if (size > 0)
/* don't write out a null byte if the buf size is zero */
*end = '\0';
/* the trailing null byte doesn't count towards the total
* ++str;
*/
return str-buf;
}
/**
* vscnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @args: Arguments for the format string
*
* The return value is the number of characters which have been written into
* the @buf not including the trailing '\0'. If @size is <= 0 the function
* returns 0.
*
* Call this function if you are already dealing with a va_list.
* You probably want scnprintf instead.
*/
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
unsigned int i;
i=vsnprintf(buf,size,fmt,args);
return (i >= size) ? (size - 1) : i;
}
/**
* snprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The return value is the number of characters which would be
* generated for the given input, excluding the trailing null,
* as per ISO C99. If the return is greater than or equal to
* @size, the resulting string is truncated.
*/
int snprintf(char * buf, size_t size, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=vsnprintf(buf,size,fmt,args);
va_end(args);
return i;
}
/**
* scnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @size: The size of the buffer, including the trailing null space
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The return value is the number of characters written into @buf not including
* the trailing '\0'. If @size is <= 0 the function returns 0. If the return is
* greater than or equal to @size, the resulting string is truncated.
*/
int scnprintf(char * buf, size_t size, const char *fmt, ...)
{
va_list args;
unsigned int i;
va_start(args, fmt);
i = vsnprintf(buf, size, fmt, args);
va_end(args);
return (i >= size) ? (size - 1) : i;
}
/**
* vsprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @args: Arguments for the format string
*
* The function returns the number of characters written
* into @buf. Use vsnprintf or vscnprintf in order to avoid
* buffer overflows.
*
* Call this function if you are already dealing with a va_list.
* You probably want sprintf instead.
*/
int vsprintf(char *buf, const char *fmt, va_list args)
{
return vsnprintf(buf, INT_MAX, fmt, args);
}
/**
* sprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @...: Arguments for the format string
*
* The function returns the number of characters written
* into @buf. Use snprintf or scnprintf in order to avoid
* buffer overflows.
*/
int sprintf(char * buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i=vsnprintf(buf, INT_MAX, fmt, args);
va_end(args);
return i;
}
/**
* vsscanf - Unformat a buffer into a list of arguments
* @buf: input buffer
* @fmt: format of buffer
* @args: arguments
*/
int vsscanf(const char * buf, const char * fmt, va_list args)
{
const char *str = buf;
char *next;
char digit;
int num = 0;
int qualifier;
int base;
int field_width;
int is_sign = 0;
while(*fmt && *str) {
/* skip any white space in format */
/* white space in format matchs any amount of
* white space, including none, in the input.
*/
if (isspace(*fmt)) {
while (isspace(*fmt))
++fmt;
while (isspace(*str))
++str;
}
/* anything that is not a conversion must match exactly */
if (*fmt != '%' && *fmt) {
if (*fmt++ != *str++)
break;
continue;
}
if (!*fmt)
break;
++fmt;
/* skip this conversion.
* advance both strings to next white space
*/
if (*fmt == '*') {
while (!isspace(*fmt) && *fmt)
fmt++;
while (!isspace(*str) && *str)
str++;
continue;
}
/* get field width */
field_width = -1;
if (isdigit(*fmt))
field_width = skip_atoi(&fmt);
/* get conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
*fmt == 'Z' || *fmt == 'z') {
qualifier = *fmt++;
if (qualifier == *fmt) {
if (qualifier == 'h') {
qualifier = 'H';
fmt++;
} else if (qualifier == 'l') {
qualifier = 'L';
fmt++;
}
}
}
base = 10;
is_sign = 0;
if (!*fmt || !*str)
break;
switch(*fmt++) {
case 'c':
{
char *s = (char *) va_arg(args,char*);
if (field_width == -1)
field_width = 1;
do {
*s++ = *str++;
} while (--field_width > 0 && *str);
num++;
}
continue;
case 's':
{
char *s = (char *) va_arg(args, char *);
if(field_width == -1)
field_width = INT_MAX;
/* first, skip leading white space in buffer */
while (isspace(*str))
str++;
/* now copy until next white space */
while (*str && !isspace(*str) && field_width--) {
*s++ = *str++;
}
*s = '\0';
num++;
}
continue;
case 'n':
/* return number of characters read so far */
{
int *i = (int *)va_arg(args,int*);
*i = str - buf;
}
continue;
case 'o':
base = 8;
break;
case 'x':
case 'X':
base = 16;
break;
case 'i':
base = 0;
case 'd':
is_sign = 1;
case 'u':
break;
case '%':
/* looking for '%' in str */
if (*str++ != '%')
return num;
continue;
default:
/* invalid format; stop here */
return num;
}
/* have some sort of integer conversion.
* first, skip white space in buffer.
*/
while (isspace(*str))
str++;
digit = *str;
if (is_sign && digit == '-')
digit = *(str + 1);
if (!digit
|| (base == 16 && !isxdigit(digit))
|| (base == 10 && !isdigit(digit))
|| (base == 8 && (!isdigit(digit) || digit > '7'))
|| (base == 0 && !isdigit(digit)))
break;
switch(qualifier) {
case 'H': /* that's 'hh' in format */
if (is_sign) {
signed char *s = (signed char *) va_arg(args,signed char *);
*s = (signed char) simple_strtol(str,&next,base);
} else {
unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
*s = (unsigned char) simple_strtoul(str, &next, base);
}
break;
case 'h':
if (is_sign) {
short *s = (short *) va_arg(args,short *);
*s = (short) simple_strtol(str,&next,base);
} else {
unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
*s = (unsigned short) simple_strtoul(str, &next, base);
}
break;
case 'l':
if (is_sign) {
long *l = (long *) va_arg(args,long *);
*l = simple_strtol(str,&next,base);
} else {
unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
*l = simple_strtoul(str,&next,base);
}
break;
case 'L':
if (is_sign) {
long long *l = (long long*) va_arg(args,long long *);
*l = simple_strtoll(str,&next,base);
} else {
unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
*l = simple_strtoull(str,&next,base);
}
break;
case 'Z':
case 'z':
{
size_t *s = (size_t*) va_arg(args,size_t*);
*s = (size_t) simple_strtoul(str,&next,base);
}
break;
default:
if (is_sign) {
int *i = (int *) va_arg(args, int*);
*i = (int) simple_strtol(str,&next,base);
} else {
unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
*i = (unsigned int) simple_strtoul(str,&next,base);
}
break;
}
num++;
if (!next)
break;
str = next;
}
return num;
}
/**
* sscanf - Unformat a buffer into a list of arguments
* @buf: input buffer
* @fmt: formatting of buffer
* @...: resulting arguments
*/
int sscanf(const char * buf, const char * fmt, ...)
{
va_list args;
int i;
va_start(args,fmt);
i = vsscanf(buf,fmt,args);
va_end(args);
return i;
}
File diff suppressed because it is too large Load Diff