Re: Gotos

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>>>> "Phil" == Phil White <cerise@littlegreenmen.armory.com> writes:
Phil> Since we're off list, I'll continue.
[back into knml, it is not offtopic, AFAICT]

Phil> I had an interesting first hand experience with this a number of years
Phil> ago.  I'll grant it was C++, but the challenge was to create a fast
Phil> fibonacci generator.  My initial attempt used the well known function
Phil> to generate an i-th digit once it was past a certain point (I believe
Phil> it was i=30 where it was faster do deal with the arithmetic).

Phil> A friend of mine generated almost identical code (we think very much
Phil> alike) and yet his was significantly faster.  No particularly good
Phil> reason algorithmically.  

Phil> The difference was entirely in the parse.  Our arithmetic was the
Phil> same, but he reversed the two sums and it ended up being faster.

  Can we look at this fibonacci example ?  I'd be really suprised if a
compiler, which does even remotely decent instructions scheduling to
depend on the order of expression in the source code (given that the
correctness of the program does not depend on the order, i.e. the
expressions are not related buy data flow).

Phil> If you aren't using larger bits of code, you miss those interactions.
Phil> Small bits of code are good for showing a compiler's ability to do
Phil> a certain optimization.  They fail miserably at any real world test
Phil> of whether or not it appears in more complex code.  

  Handwaving.

  Your anectodal example is not an evidence.  Your conclusions that
compilers "fail miserably on at any real world test" are totaly bogus.
The obvious evidence being that some compilers produce significantly
better code that other compilers and (usually) newer compiler versions
produce better code than the older compiler versions.

Phil> In this particular case, we're talking about kernel code which is
Phil> referenced in a few places.  There is a very high probability that
Phil> some optimizations which would be caught in theory are skimmed over
Phil> in a more complex AST.   

  I see no point in instroducing probabilities in a discussion about a
deterministic process like compilation.

Phil> If you don't believe me, there's code which is freely available
Phil> over the net to prove it.  It's the direct-io.c in the kernel which
Phil> was referenced in the discussion.

  Believe in what? I'm not religious, so I don't believe in anything.
I can be CONVINCED though.  First my knowledge of compilers tells me
what a compiler can or can't do (admittedly I do not develop
compilers) and second my expectations are confirmed by a number of
"real world" examples.

  So, if you don't like my example programs, we'll use direct-io.c.
I've attached two patches (against 2.6.1). In direct-io.c.else.diff,
instead of goto we use an "else if" and in direct-io.c.ret.diff we
place a return statement.  Also attached are the outputs from the
original direct-io.c, with the "else" patch applied and with the "ret"
patch applied (I've left only dio_refill_pages function).

  There isn't ANY difference between direct-io.s.orig and
direct-io.s.else.

  There's no essential difference between direct-io.s.orig and
direct-io.s.ret, both compilations have the same control flow graph,
with the same instructions in the basic blocks.  There's one
instruction more in direct-io.s.ret (the "xorl %eax, %eax" before "jmp
.L1"), but in that path direct-io.s.ret executes one instruction less
than direct-io.s.orig.

  This again confirms my initial opinion that the compiler would
generate essentially the same code with or without the goto.

  As an extra bonus, I've attached the outputs for the ARM
architecture.  Again, the original and the "else" variants are
identical.  The original and the "ret" variant contain the same number
of instructions, but the original variant does execute two
instructions more, one being a jump.

Phil> On Mon, Jan 12, 2004 at 10:06:33AM +0200, Momchil Velikov wrote:
>> >>>>> "Phil" == Phil White <cerise@littlegreenmen.armory.com> writes:
>> 
Phil> No problems with your criteria, but rather your example.  Small code
Phil> does not lend itself reasonably to a demonstration of the compiler's
Phil> expected output. 
>> 
>> Oh, yes it does. The compiler is hardly concerned with the absolute
>> size (number of statements and variables) of the functions, but rather
>> with specific disposition of data- and control- flow information --
>> pretty well captured by small examples.

Please, avoid bottom-posting.  Thanks.

~velco
--- direct-io.c.orig	2004-01-13 10:48:25.000000000 +0200
+++ direct-io.c.else	2004-01-13 10:51:13.000000000 +0200
@@ -163,17 +163,14 @@ static int dio_refill_pages(struct dio *
 		dio->head = 0;
 		dio->tail = 1;
 		ret = 0;
-		goto out;
-	}
-
-	if (ret >= 0) {
+	} else if (ret >= 0) {
 		dio->curr_user_address += ret * PAGE_SIZE;
 		dio->curr_page += ret;
 		dio->head = 0;
 		dio->tail = ret;
 		ret = 0;
 	}
-out:
+
 	return ret;	
 }
 
--- direct-io.c.orig	2004-01-13 10:48:25.000000000 +0200
+++ direct-io.c.ret	2004-01-13 11:02:44.000000000 +0200
@@ -162,10 +162,9 @@ static int dio_refill_pages(struct dio *
 		dio->pages[0] = ZERO_PAGE(dio->curr_user_address);
 		dio->head = 0;
 		dio->tail = 1;
-		ret = 0;
-		goto out;
+		return 0;
 	}
-
+	
 	if (ret >= 0) {
 		dio->curr_user_address += ret * PAGE_SIZE;
 		dio->curr_page += ret;
@@ -173,7 +172,7 @@ static int dio_refill_pages(struct dio *
 		dio->tail = ret;
 		ret = 0;
 	}
-out:
+
 	return ret;	
 }
 
	.file	"direct-io.c"
	.text
	.p2align 4,,15
	.type	dio_refill_pages, @function
dio_refill_pages:
	pushl	%edi
	movl	$64, %ecx
	pushl	%esi
	pushl	%ebx
	subl	$32, %esp
	movl	$-8192, %ebx
	movl	48(%esp), %edi
	movl	132(%edi), %edx
	movl	136(%edi), %eax
	subl	%edx, %eax
	cmpl	$65, %eax
	cmovl	%eax, %ecx
#APP
	andl %esp,%ebx; 
#NO_APP
	movl	(%ebx), %eax
	movl	104(%eax), %esi
	leal	32(%esi), %edx
	movl	%edx, %eax
#APP
	# beginning down_read
	lock ;   incl      (%eax)
	  js        2f
	1:
	.subsection 1
	.ifndef .text.lock.direct_io
	.text.lock.direct_io:
	.endif
	2:
	  pushl     %ecx
	  pushl     %edx
	  call      rwsem_down_read_failed
	  popl      %edx
	  popl      %ecx
	  jmp       1b
.previous
	# ending down_read
	
#NO_APP
	xorl	%eax, %eax
	movl	(%ebx), %edx
	movl	%eax, 28(%esp)
	leal	144(%edi), %eax
	movl	%eax, 24(%esp)
	xorl	%eax, %eax
	movl	%eax, 20(%esp)
	xorl	%eax, %eax
	cmpl	$0, 8(%edi)
	movl	%ecx, 12(%esp)
	sete	%al
	movl	%eax, 16(%esp)
	movl	140(%edi), %eax
	movl	%eax, 8(%esp)
	movl	104(%edx), %eax
	movl	%edx, (%esp)
	movl	%eax, 4(%esp)
	call	get_user_pages
	movl	%eax, %esi
	movl	$-1, %edx
	movl	(%ebx), %eax
	movl	104(%eax), %ecx
	leal	32(%ecx), %eax
#APP
	# beginning __up_read
	lock ;   xadd      %edx,(%eax)
	  js        2f
	1:
	.subsection 1
	.ifndef .text.lock.direct_io
	.text.lock.direct_io:
	.endif
	2:
	  decw      %dx
	  jnz       1b
	  pushl     %ecx
	  call      rwsem_wake
	  popl      %ecx
	  jmp       1b
.previous
	# ending __up_read

#NO_APP
	testl	%esi, %esi
	js	.L22
.L20:
	addl	%esi, 132(%edi)
	movl	%esi, %eax
	sall	$12, %eax
	addl	%eax, 140(%edi)
	xorl	%eax, %eax
	movl	%eax, 400(%edi)
	movl	%esi, 404(%edi)
.L21:
	xorl	%esi, %esi
.L18:
	addl	$32, %esp
	movl	%esi, %eax
	popl	%ebx
	popl	%esi
	popl	%edi
	ret
	.p2align 4,,7
.L22:
	movl	32(%edi), %eax
	testl	%eax, %eax
	je	.L16
	cmpl	$1, 8(%edi)
	je	.L23
.L16:
	testl	%esi, %esi
	jns	.L20
	jmp	.L18
.L23:
	movl	408(%edi), %ebx
	testl	%ebx, %ebx
	jne	.L17
	movl	%esi, 408(%edi)
.L17:
	movl	mem_map, %edx
	movl	$empty_zero_page+1073741824, %eax
	xorl	%ecx, %ecx
	movl	%ecx, 400(%edi)
	shrl	$12, %eax
	leal	(%eax,%eax,4), %eax
	leal	(%edx,%eax,8), %eax
	movl	$1, %edx
	movl	%eax, 144(%edi)
	movl	%edx, 404(%edi)
	jmp	.L21
	.file	"direct-io.c"
	.text
	.p2align 4,,15
	.type	dio_refill_pages, @function
dio_refill_pages:
	pushl	%edi
	movl	$64, %ecx
	pushl	%esi
	pushl	%ebx
	subl	$32, %esp
	movl	$-8192, %ebx
	movl	48(%esp), %edi
	movl	132(%edi), %edx
	movl	136(%edi), %eax
	subl	%edx, %eax
	cmpl	$65, %eax
	cmovl	%eax, %ecx
#APP
	andl %esp,%ebx; 
#NO_APP
	movl	(%ebx), %eax
	movl	104(%eax), %esi
	leal	32(%esi), %edx
	movl	%edx, %eax
#APP
	# beginning down_read
	lock ;   incl      (%eax)
	  js        2f
	1:
	.subsection 1
	.ifndef .text.lock.direct_io
	.text.lock.direct_io:
	.endif
	2:
	  pushl     %ecx
	  pushl     %edx
	  call      rwsem_down_read_failed
	  popl      %edx
	  popl      %ecx
	  jmp       1b
.previous
	# ending down_read
	
#NO_APP
	xorl	%eax, %eax
	movl	(%ebx), %edx
	movl	%eax, 28(%esp)
	leal	144(%edi), %eax
	movl	%eax, 24(%esp)
	xorl	%eax, %eax
	movl	%eax, 20(%esp)
	xorl	%eax, %eax
	cmpl	$0, 8(%edi)
	movl	%ecx, 12(%esp)
	sete	%al
	movl	%eax, 16(%esp)
	movl	140(%edi), %eax
	movl	%eax, 8(%esp)
	movl	104(%edx), %eax
	movl	%edx, (%esp)
	movl	%eax, 4(%esp)
	call	get_user_pages
	movl	%eax, %esi
	movl	$-1, %edx
	movl	(%ebx), %eax
	movl	104(%eax), %ecx
	leal	32(%ecx), %eax
#APP
	# beginning __up_read
	lock ;   xadd      %edx,(%eax)
	  js        2f
	1:
	.subsection 1
	.ifndef .text.lock.direct_io
	.text.lock.direct_io:
	.endif
	2:
	  decw      %dx
	  jnz       1b
	  pushl     %ecx
	  call      rwsem_wake
	  popl      %ecx
	  jmp       1b
.previous
	# ending __up_read

#NO_APP
	testl	%esi, %esi
	js	.L20
.L19:
	addl	%esi, 132(%edi)
	movl	%esi, %eax
	sall	$12, %eax
	addl	%eax, 140(%edi)
	xorl	%eax, %eax
	movl	%esi, 404(%edi)
	xorl	%esi, %esi
	movl	%eax, 400(%edi)
.L18:
	movl	%esi, %eax
.L1:
	addl	$32, %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	ret
	.p2align 4,,7
.L20:
	movl	32(%edi), %eax
	testl	%eax, %eax
	je	.L16
	cmpl	$1, 8(%edi)
	je	.L21
.L16:
	testl	%esi, %esi
	jns	.L19
	jmp	.L18
.L21:
	movl	408(%edi), %ebx
	testl	%ebx, %ebx
	jne	.L17
	movl	%esi, 408(%edi)
.L17:
	movl	mem_map, %edx
	movl	$empty_zero_page+1073741824, %eax
	xorl	%ecx, %ecx
	movl	%ecx, 400(%edi)
	shrl	$12, %eax
	leal	(%eax,%eax,4), %eax
	leal	(%edx,%eax,8), %eax
	movl	$1, %edx
	movl	%eax, 144(%edi)
	xorl	%eax, %eax
	movl	%edx, 404(%edi)
	jmp	.L1
	.file	"direct-io.c"
	.text
	.align	2
	.type	dio_refill_pages, %function
dio_refill_pages:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, fp, ip, lr, pc}
	sub	fp, ip, #4
	sub	sp, sp, #16
	bic	r5, sp, #8128
	bic	r5, r5, #63
	ldr	r3, [r5, #12]
	mov	r6, r0
	ldr	r0, [r3, #104]
	add	r3, r6, #136
	ldmda	r3, {r3, r4}
	sub	r4, r4, r3
	add	r0, r0, #32
	bl	__down_read
	ldr	r0, [r5, #12]
	ldr	ip, [r6, #8]
	cmp	r4, #64
	movge	r4, #64
	ldr	r1, [r0, #104]
	ldr	r2, [r6, #140]
	cmp	ip, #0
	movne	ip, #0
	moveq	ip, #1
	mov	r7, #0
	mov	r3, r4
	add	lr, r6, #144
	str	ip, [sp, #0]
	stmib	sp, {r7, lr}	@ phole stm
	str	r7, [sp, #12]
	bl	get_user_pages
	ldr	r3, [r5, #12]
	mov	r4, r0
	ldr	r0, [r3, #104]
	add	r0, r0, #32
	bl	__up_read
	cmp	r4, r7
	mov	r1, r7
	bge	.L17
	ldr	r3, [r6, #32]
	cmp	r3, r7
	beq	.L13
	ldr	r2, [r6, #8]
	cmp	r2, #1
	bne	.L13
	ldr	r3, [r6, #408]
	cmp	r3, r7
	ldr	r3, .L18
	streq	r4, [r6, #408]
	ldr	r3, [r3, #0]
	mov	r4, r7
	str	r2, [r6, #404]
	str	r3, [r6, #144]
	str	r7, [r6, #400]
	b	.L15
.L13:
	cmp	r4, #0
	blt	.L15
.L17:
	ldr	r3, [r6, #140]
	ldr	r2, [r6, #132]
	add	r3, r3, r4, asl #12
	add	r2, r2, r4
	str	r4, [r6, #404]
	str	r1, [r6, #400]
	mov	r4, r1
	str	r3, [r6, #140]
	str	r2, [r6, #132]
.L15:
	mov	r0, r4
	ldmea	fp, {r4, r5, r6, r7, fp, sp, pc}
.L19:
	.align	2
.L18:
	.word	empty_zero_page
	.size	dio_refill_pages, .-dio_refill_pages
	.align	2
	.type	dio_get_page, %function
dio_get_page:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	add	r2, r0, #404
	ldmda	r2, {r2, r3}
	sub	r3, r3, r2
	mov	r4, r0
	cmp	r3, #0
	bne	.L21
	bl	dio_refill_pages
	subs	r2, r0, #0
	bne	.L20
	add	r2, r4, #404
	ldmda	r2, {r2, r3}
	sub	r3, r3, r2
	cmp	r3, #0
	streq	r0, [r0, #0]
.L21:
	ldr	r3, [r4, #400]
	add	r2, r4, r3, asl #2
	ldr	r2, [r2, #144]
	add	r3, r3, #1
	str	r3, [r4, #400]
.L20:
	mov	r0, r2
	ldmea	fp, {r4, fp, sp, pc}
	.size	dio_get_page, .-dio_get_page
	.align	2
	.type	dio_complete, %function
dio_complete:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	sub	sp, sp, #4
	ldr	r4, [r0, #56]
	cmp	r4, #0
	ldrne	ip, [r0, #104]
	ldrne	r0, [r0, #4]
	strne	ip, [sp, #0]
	movne	lr, pc
	movne	pc, r4
.L28:
	ldmea	fp, {r4, fp, sp, pc}
	.size	dio_complete, .-dio_complete
	.align	2
	.type	finished_one_bio, %function
finished_one_bio:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	mov	r4, r0
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r0, #412]
	sub	r3, r3, #1
	str	r3, [r0, #412]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	bne	.L30
	ldr	r3, [r0, #432]
	cmp	r3, #0
	beq	.L30
	ldr	ip, [r0, #12]
	ldr	r1, [r0, #28]
	ldr	r3, [r0, #436]
	mov	r1, r1, asl ip
	mov	r2, #0
	bl	dio_complete
	ldr	r0, [r4, #428]
	ldr	r1, [r4, #436]
	mov	r2, #0
	bl	aio_complete
	mov	r0, r4
	ldmea	fp, {r4, fp, sp, lr}
	b	kfree
.L30:
	ldmea	fp, {r4, fp, sp, pc}
	.size	finished_one_bio, .-finished_one_bio
	.align	2
	.type	dio_bio_end_aio, %function
dio_bio_end_aio:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r4, [r0, #28]
	mov	r1, r0
	cmp	r4, #0
	mov	r3, #1
	ldr	r0, [r0, #48]
	bne	.L34
	bl	dio_bio_complete
	mov	r3, r4
.L34:
	mov	r0, r3
	ldmea	fp, {r4, fp, sp, pc}
	.size	dio_bio_end_aio, .-dio_bio_end_aio
	.align	2
	.type	dio_bio_end_io, %function
dio_bio_end_io:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r3, [r0, #28]
	mov	r2, #1
	cmp	r3, #0
	ldr	r1, [r0, #48]
	bne	.L36
	mrs	r4, cpsr		@ local_irq_save
	orr	r3, r4, #128
	msr	cpsr_c, r3
	ldr	r3, [r1, #420]
	str	r3, [r0, #48]
	str	r0, [r1, #420]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r1, #416]
	sub	r3, r3, #1
	str	r3, [r1, #416]
	msr	cpsr_c, r2		@ local_irq_restore

	ldr	r0, [r1, #424]
	cmp	r0, #0
	beq	.L44
	ldr	r3, [r1, #416]
	cmp	r3, #0
	bleq	wake_up_process
.L44:
	msr	cpsr_c, r4		@ local_irq_restore

	mov	r2, #0
.L36:
	mov	r0, r2
	ldmea	fp, {r4, fp, sp, pc}
	.size	dio_bio_end_io, .-dio_bio_end_io
	.align	2
	.type	dio_bio_alloc, %function
dio_bio_alloc:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, fp, ip, lr, pc}
	sub	fp, ip, #4
	mov	r6, r0
	mov	r5, r1
	mov	r0, #208
	mov	r1, r3
	mov	r4, r2
	bl	bio_alloc
	cmp	r0, #0
	mvn	r3, #11
	beq	.L46
	str	r5, [r0, #8]
	str	r4, [r0, #0]
	ldr	r3, [r6, #432]
	cmp	r3, #0
	ldrne	r3, .L51
	ldreq	r3, .L51+4
	str	r3, [r0, #40]
	str	r0, [r6, #0]
	mov	r3, #0
.L46:
	mov	r0, r3
	ldmea	fp, {r4, r5, r6, fp, sp, pc}
.L52:
	.align	2
.L51:
	.word	dio_bio_end_aio
	.word	dio_bio_end_io
	.size	dio_bio_alloc, .-dio_bio_alloc
	.align	2
	.type	dio_bio_submit, %function
dio_bio_submit:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r5, [r0, #0]
	mov	r4, r0
	str	r0, [r5, #48]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r0, #412]
	add	r3, r3, #1
	str	r3, [r0, #412]
	msr	cpsr_c, r2		@ local_irq_restore

	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r0, #416]
	add	r3, r3, #1
	str	r3, [r0, #416]
	msr	cpsr_c, r2		@ local_irq_restore

	ldr	r3, [r0, #432]
	cmp	r3, #0
	beq	.L56
	ldr	r3, [r0, #8]
	mov	r0, r5
	cmp	r3, #0
	bleq	bio_set_pages_dirty
.L56:
	ldr	r0, [r4, #8]
	mov	r1, r5
	bl	submit_bio
	mov	r3, #0
	str	r3, [r4, #44]
	str	r3, [r4, #0]
	ldmea	fp, {r4, r5, fp, sp, pc}
	.size	dio_bio_submit, .-dio_bio_submit
	.align	2
	.type	dio_cleanup, %function
dio_cleanup:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	add	r2, r0, #404
	ldmda	r2, {r2, r3}
	sub	r3, r3, r2
	mov	r4, r0
	cmp	r3, #0
	beq	.L70
.L68:
	mov	r0, r4
	bl	dio_get_page
	ldr	r3, [r0, #0]
	mov	r1, r0
	tst	r3, #2048
	bne	.L58
	ldr	r3, [r0, #4]
	cmp	r3, #0
	streq	r3, [r3, #0]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r1, #4]
	sub	r3, r3, #1
	str	r3, [r1, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	bleq	__page_cache_release
.L58:
	add	r2, r4, #404
	ldmda	r2, {r2, r3}
	sub	r3, r3, r2
	cmp	r3, #0
	bne	.L68
.L70:
	ldmea	fp, {r4, fp, sp, pc}
	.size	dio_cleanup, .-dio_cleanup
	.align	2
	.type	dio_await_one, %function
dio_await_one:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, fp, ip, lr, pc}
	sub	fp, ip, #4
	mov	r4, r0
	mrs	r1, cpsr		@ local_irq_save
	orr	r3, r1, #128
	msr	cpsr_c, r3
	ldr	r3, [r0, #420]
	cmp	r3, #0
	bne	.L98
.L93:
	bic	r5, sp, #8128
	bic	r5, r5, #63
	ldr	r2, [r5, #12]
	mov	r3, #2
	str	r3, [r2, #0]
	ldr	r6, [r4, #420]
	cmp	r6, #0
	bne	.L81
	ldr	r3, [r5, #12]
	str	r3, [r4, #424]
	msr	cpsr_c, r1		@ local_irq_restore

	bl	blk_run_queues
	bl	io_schedule
	mrs	r1, cpsr		@ local_irq_save
	orr	r3, r1, #128
	msr	cpsr_c, r3
	str	r6, [r4, #424]
.L81:
	ldr	r3, [r5, #12]
	mov	r2, #0
	str	r2, [r3, #0]
	ldr	r3, [r4, #420]
	cmp	r3, r2
	beq	.L93
.L98:
	ldr	r0, [r4, #420]
	ldr	r3, [r0, #48]
	str	r3, [r4, #420]
	msr	cpsr_c, r1		@ local_irq_restore

	ldmea	fp, {r4, r5, r6, fp, sp, pc}
	.size	dio_await_one, .-dio_await_one
	.align	2
	.type	dio_bio_complete, %function
dio_bio_complete:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, r8, sl, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r3, [r1, #12]
	mov	r7, r0
	ands	sl, r3, #1
	mvneq	r3, #4
	ldr	r2, [r1, #36]
	streq	r3, [r0, #436]
	ldr	r3, [r7, #432]
	mov	r5, r1
	cmp	r3, #0
	beq	.L102
	ldr	r3, [r7, #8]
	cmp	r3, #0
	bne	.L102
	mov	r0, r5
	bl	bio_check_pages_dirty
	b	.L103
.L102:
	ldrh	r3, [r5, #20]
	mov	r8, #0
	cmp	r8, r3
	bge	.L119
	mov	r6, r2
.L115:
	ldr	r3, [r7, #8]
	ldr	r4, [r6, #0]
	cmp	r3, #0
	mov	r0, r4
	add	r6, r6, #12
	bleq	set_page_dirty_lock
.L108:
	ldr	r3, [r4, #0]
	tst	r3, #2048
	bne	.L106
	ldr	r3, [r4, #4]
	cmp	r3, #0
	streq	r3, [r3, #0]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r4, #4]
	sub	r3, r3, #1
	str	r3, [r4, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	mov	r0, r4
	bleq	__page_cache_release
.L106:
	ldrh	r3, [r5, #20]
	add	r8, r8, #1
	cmp	r8, r3
	blt	.L115
.L119:
	mov	r0, r5
	bl	bio_put
.L103:
	mov	r0, r7
	bl	finished_one_bio
	cmp	sl, #0
	movne	r0, #0
	mvneq	r0, #4
	ldmea	fp, {r4, r5, r6, r7, r8, sl, fp, sp, pc}
	.size	dio_bio_complete, .-dio_bio_complete
	.align	2
	.type	dio_await_completion, %function
dio_await_completion:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r3, [r0, #0]
	mov	r5, #0
	cmp	r3, r5
	mov	r4, r0
	blne	dio_bio_submit
.L121:
	ldr	r3, [r4, #412]
	cmp	r3, #0
	beq	.L128
.L126:
	mov	r0, r4
	bl	dio_await_one
	mov	r1, r0
	mov	r0, r4
	bl	dio_bio_complete
	ldr	r3, [r4, #412]
	cmp	r5, #0
	moveq	r5, r0
	cmp	r3, #0
	bne	.L126
.L128:
	mov	r0, r5
	ldmea	fp, {r4, r5, fp, sp, pc}
	.size	dio_await_completion, .-dio_await_completion
	.align	2
	.type	dio_bio_reap, %function
dio_bio_reap:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r3, [r0, #48]
	mov	r4, r0
	cmp	r3, #63
	add	r3, r3, #1
	mov	r0, #0
	str	r3, [r4, #48]
	ble	.L130
	ldr	r3, [r4, #420]
	cmp	r3, r0
	beq	.L142
.L140:
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r1, [r4, #420]
	ldr	r3, [r1, #48]
	str	r3, [r4, #420]
	msr	cpsr_c, r2		@ local_irq_restore

	mov	r0, r4
	bl	dio_bio_complete
	ldr	r3, [r4, #420]
	cmp	r3, #0
	bne	.L140
.L142:
	mov	r3, #0
	str	r3, [r4, #48]
.L130:
	ldmea	fp, {r4, fp, sp, pc}
	.size	dio_bio_reap, .-dio_bio_reap
	.align	2
	.type	get_more_blocks, %function
get_more_blocks:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	sub	sp, sp, #4
	mov	r4, r0
	ldr	r0, [r0, #408]
	add	r2, r4, #68
	cmp	r0, #0
	mov	r3, r2
	bne	.L144
	str	r0, [r2, #20]
	ldr	r1, [r4, #28]
	ldr	r2, [r4, #36]
	str	r0, [r4, #68]
	cmp	r1, r2
	strcs	r0, [r0, #0]
	ldr	ip, [r4, #16]
	ldr	r1, [r4, #28]
	ldr	r0, [r4, #36]
	mov	r2, #1
	rsb	r0, r1, r0
	mov	r2, r2, asl ip
	mov	lr, r0, lsr ip
	sub	r2, r2, #1
	mov	r1, r1, lsr ip
	ldr	ip, [r4, #8]
	tst	r0, r2
	addne	lr, lr, #1
	cmp	ip, #1
	movne	ip, #0
	moveq	ip, #1
	ldr	r0, [r4, #4]
	mov	r2, lr
	str	ip, [sp, #0]
	mov	lr, pc
	ldr	pc, [r4, #52]
.L144:
	ldmea	fp, {r4, fp, sp, pc}
	.size	get_more_blocks, .-get_more_blocks
	.align	2
	.type	dio_new_bio, %function
dio_new_bio:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, r8, fp, ip, lr, pc}
	sub	fp, ip, #4
	mov	r8, r1
	mov	r7, r0
	bl	dio_bio_reap
	cmp	r0, #0
	mov	r6, r0
	bne	.L150
	ldr	r0, [r7, #96]
	ldr	r4, [r7, #12]
	ldr	r5, [r7, #24]
	bl	bio_get_nr_vecs
	mov	r1, r0
	cmp	r1, r5
	movge	r1, r5
	subs	r3, r1, #0
	sub	r4, r4, #9
	strle	r6, [r6, #0]
	mov	r4, r8, asl r4
	mov	r2, r4
	mov	r0, r7
	ldr	r1, [r7, #96]
	bl	dio_bio_alloc
	mov	r3, #0
	mov	r6, r0
	str	r3, [r7, #44]
.L150:
	mov	r0, r6
	ldmea	fp, {r4, r5, r6, r7, r8, fp, sp, pc}
	.size	dio_new_bio, .-dio_new_bio
	.align	2
	.type	dio_bio_add_page, %function
dio_bio_add_page:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, fp, ip, lr, pc}
	sub	fp, ip, #4
	mov	r4, r0
	ldr	r3, [r4, #120]
	ldr	r0, [r0, #0]
	ldr	r1, [r4, #116]
	ldr	r2, [r4, #124]
	bl	bio_add_page
	ldr	r3, [r4, #124]
	cmp	r0, r3
	bne	.L154
	ldr	r3, [r4, #24]
	ldr	r1, [r4, #116]
	sub	r3, r3, #1
	str	r3, [r4, #24]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r1, #4]
	add	r3, r3, #1
	str	r3, [r1, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	ldr	r1, [r4, #124]
	ldr	r2, [r4, #12]
	ldr	r3, [r4, #128]
	mov	r0, #0
	add	r3, r3, r1, lsr r2
	str	r3, [r4, #60]
	ldmea	fp, {r4, fp, sp, pc}
.L154:
	mov	r0, #1
	ldmea	fp, {r4, fp, sp, pc}
	.size	dio_bio_add_page, .-dio_bio_add_page
	.align	2
	.type	dio_send_cur_page, %function
dio_send_cur_page:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r3, [r0, #0]
	mov	r5, #0
	cmp	r3, r5
	mov	r4, r0
	beq	.L169
	ldr	r2, [r0, #60]
	ldr	r3, [r0, #128]
	cmp	r2, r3
	blne	dio_bio_submit
.L160:
	ldr	r3, [r4, #44]
	cmp	r3, #0
	movne	r0, r4
	blne	dio_bio_submit
.L159:
	ldr	r3, [r4, #0]
	cmp	r3, #0
	bne	.L162
.L169:
	ldr	r1, [r4, #128]
	mov	r0, r4
	bl	dio_new_bio
	cmp	r0, #0
	mov	r5, r0
	bne	.L164
.L162:
	mov	r0, r4
	bl	dio_bio_add_page
	cmp	r0, #0
	beq	.L164
	mov	r0, r4
	bl	dio_bio_submit
	ldr	r1, [r4, #128]
	mov	r0, r4
	bl	dio_new_bio
	cmp	r0, #0
	mov	r5, r0
	bne	.L164
	mov	r0, r4
	bl	dio_bio_add_page
	cmp	r0, #0
	movne	r3, #0
	mov	r5, r0
	strne	r3, [r3, #0]
.L164:
	mov	r0, r5
	ldmea	fp, {r4, r5, fp, sp, pc}
	.size	dio_send_cur_page, .-dio_send_cur_page
	.align	2
	.type	submit_page_section, %function
submit_page_section:
	@ args = 4, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, r8, sl, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	ip, [r0, #116]
	mov	r4, r0
	cmp	ip, r1
	mov	r5, r1
	mov	r7, r2
	mov	r8, r3
	ldr	sl, [fp, #4]
	mov	r6, #0
	bne	.L171
	add	r2, r0, #120
	ldmia	r2, {r2, r3}
	add	r3, r2, r3
	ldr	r1, [r0, #124]
	cmp	r3, r7
	bne	.L171
	ldr	r2, [r0, #12]
	ldr	r3, [r0, #128]
	add	r3, r3, r1, lsr r2
	cmp	r3, sl
	bne	.L171
	ldr	r3, [r0, #44]
	add	r2, r1, r8
	cmp	r3, r6
	str	r2, [r0, #124]
	beq	.L179
	bl	dio_send_cur_page
	mov	r6, r0
	ldr	r0, [r4, #116]
	ldr	r3, [r0, #0]
	tst	r3, #2048
	bne	.L178
	ldr	r3, [r0, #4]
	cmp	r3, #0
	streq	r3, [r3, #0]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r0, #4]
	sub	r3, r3, #1
	str	r3, [r0, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	bleq	__page_cache_release
.L178:
	mov	r3, #0
	str	r3, [r4, #116]
	b	.L179
.L171:
	cmp	ip, #0
	beq	.L180
	mov	r0, r4
	bl	dio_send_cur_page
	mov	r6, r0
	ldr	r0, [r4, #116]
	ldr	r3, [r0, #0]
	tst	r3, #2048
	bne	.L186
	ldr	r3, [r0, #4]
	cmp	r3, #0
	streq	r3, [r3, #0]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r0, #4]
	sub	r3, r3, #1
	str	r3, [r0, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	bleq	__page_cache_release
.L186:
	mov	r3, #0
	cmp	r6, #0
	str	r3, [r4, #116]
	bne	.L179
.L180:
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r5, #4]
	add	r3, r3, #1
	str	r3, [r5, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	str	sl, [r4, #128]
	str	r5, [r4, #116]
	str	r7, [r4, #120]
	str	r8, [r4, #124]
.L179:
	mov	r0, r6
	ldmea	fp, {r4, r5, r6, r7, r8, sl, fp, sp, pc}
	.size	submit_page_section, .-submit_page_section
	.align	2
	.type	clean_blockdev_aliases, %function
clean_blockdev_aliases:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, fp, ip, lr, pc}
	sub	fp, ip, #4
	ldr	r3, [r0, #32]
	mov	r5, #0
	cmp	r5, r3
	mov	r4, r0
	bcs	.L197
.L195:
	ldr	r1, [r4, #84]
	ldr	r0, [r4, #96]
	add	r1, r1, r5
	bl	unmap_underlying_metadata
	ldr	r3, [r4, #32]
	add	r5, r5, #1
	cmp	r5, r3
	bcc	.L195
.L197:
	ldmea	fp, {r4, r5, fp, sp, pc}
	.size	clean_blockdev_aliases, .-clean_blockdev_aliases
	.align	2
	.type	dio_zero_block, %function
dio_zero_block:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, fp, ip, lr, pc}
	sub	fp, ip, #4
	sub	sp, sp, #4
	ldr	r3, [r0, #16]
	mov	r2, #1
	cmp	r3, #0
	mov	r4, r0
	str	r2, [r0, #20]
	mov	lr, r1
	beq	.L198
	mov	ip, r2, asl r3
	ldr	r3, [r0, #68]
	sub	r1, ip, #1
	tst	r3, #32
	beq	.L198
	ldr	r3, [r0, #28]
	mov	r2, #0
	ands	r5, r3, r1
	beq	.L198
	ldr	r3, .L206
	cmp	lr, r2
	ldr	r1, [r3, #0]
	ldr	r3, [r4, #12]
	rsbne	r5, r5, ip
	ldr	ip, [r4, #64]
	mov	r3, r5, asl r3
	str	ip, [sp, #0]
	bl	submit_page_section
	cmp	r0, #0
	ldreq	r3, [r4, #64]
	addeq	r3, r3, r5
	streq	r3, [r4, #64]
.L198:
	ldmea	fp, {r4, r5, fp, sp, pc}
.L207:
	.align	2
.L206:
	.word	empty_zero_page
	.size	dio_zero_block, .-dio_zero_block
	.global	__ashrdi3
	.align	2
	.type	do_direct_IO, %function
do_direct_IO:
	@ args = 0, pretend = 0, frame = 8
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
	sub	fp, ip, #4
	sub	sp, sp, #12
	ldr	r2, [r0, #28]
	ldr	r3, [r0, #36]
	ldr	sl, [r0, #12]
	cmp	r2, r3
	mov	r3, #4096
	mov	r3, r3, lsr sl
	mov	r2, #0
	str	r3, [fp, #-44]
	str	r2, [fp, #-48]
	mov	r4, r0
	add	r8, r0, #68
	ldr	r7, [r0, #40]
	bcs	.L215
.L285:
	mov	r0, r4
	bl	dio_get_page
	cmn	r0, #1000
	mov	r6, r0
	strhi	r0, [fp, #-48]
	bhi	.L215
	ldr	r3, [fp, #-44]
	cmp	r7, r3
	bcs	.L217
.L278:
	ldr	r5, [r4, #32]
	mov	r9, r7, asl sl
	cmp	r5, #0
	bne	.L230
	mov	r0, r4
	bl	get_more_blocks
	cmp	r0, #0
	str	r0, [fp, #-48]
	bne	.L243
	ldr	r2, [fp, #-48]
	ldr	r3, [r8, r2, asl #2]
	tst	r3, #16
	beq	.L230
	ldr	r3, [r8, #20]
	ldr	r2, [r4, #12]
	ldr	r1, [r4, #16]
	mov	r3, r3, lsr r2
	str	r3, [r4, #32]
	ldr	r3, [r8, #16]
	mov	r3, r3, asl r1
	str	r3, [r4, #64]
	ldr	r2, [fp, #-48]
	ldr	r3, [r8, r2, asl #2]
	tst	r3, #32
	movne	r0, r4
	blne	clean_blockdev_aliases
.L231:
	ldr	r1, [r4, #16]
	cmp	r1, #0
	beq	.L230
	ldr	r2, [fp, #-48]
	ldr	r3, [r8, r2, asl #2]
	mov	r2, #1
	tst	r3, #32
	mov	r2, r2, asl r1
	ldr	r1, [r4, #28]
	ldreq	r3, [r4, #64]
	sub	r2, r2, #1
	and	r1, r1, r2
	addeq	r3, r3, r1
	streq	r3, [r4, #64]
	ldr	r3, [r4, #32]
	rsb	r3, r1, r3
	str	r3, [r4, #32]
.L230:
	ldr	r3, [r8, #0]
	mov	r3, r3, lsr #4
	ands	r5, r3, #1
	bne	.L238
	ldr	r3, [r4, #4]
	mov	r2, sl
	add	r3, r3, #52
	ldmia	r3, {r0-r1}
	bl	__ashrdi3
	ldr	r3, [r4, #28]
	mov	r2, r3
	mov	r3, #0
	cmp	r1, r3
	bgt	.L241
	bne	.L243
	cmp	r0, r2
	bhi	.L241
.L243:
	ldr	r3, [r6, r5, asl #2]
	b	.L291
.L241:
	ldr	r3, .L292
	mov	r1, #1
	ldr	r2, [r3, #0]
	movs	r1, r1, asl sl
	rsb	r2, r2, r6
	mov	r2, r2, asr #3
	add	r3, r2, r2, asl #1
	add	r3, r3, r3, asl #4
	add	r3, r3, r3, asl #8
	add	r3, r3, r3, asl #16
	add	r2, r2, r3, asl #2
	mov	r2, r2, asl #12
	add	r0, r2, #-1073741824
	addne	r0, r0, r9
	blne	__memzero
.L251:
	ldr	r1, [r6, #16]
	cmp	r1, #0
	beq	.L254
	ldr	r2, [r1, #56]
	add	r3, r1, #56
	cmp	r2, r3
	bne	.L254
	ldr	r2, [r1, #64]
	add	r3, r1, #64
	cmp	r2, r3
	bne	.L254
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r6, #0]
	orr	r3, r3, #1024
	str	r3, [r6, #0]
	msr	cpsr_c, r2		@ local_irq_restore

	b	.L260
.L254:
	mov	r0, r6
	bl	__flush_dcache_page
.L260:
	ldr	r3, [r4, #28]
	add	r7, r7, #1
	add	r3, r3, #1
	str	r3, [r4, #28]
	b	.L261
.L238:
	ldr	r3, [r4, #16]
	cmp	r3, #0
	beq	.L262
	ldr	r1, [r4, #20]
	cmp	r1, #0
	moveq	r0, r4
	bleq	dio_zero_block
.L262:
	ldr	r1, [r4, #36]
	ldr	r2, [r4, #28]
	ldr	r5, [r4, #32]
	rsb	r3, r9, #4096
	mov	r3, r3, lsr sl
	cmp	r5, r3
	movcs	r5, r3
	rsb	r3, r2, r1
	cmp	r5, r3
	movcs	r5, r3
	movs	r1, r5, asl sl
	streq	r1, [r1, #0]
	ldr	r3, [r8, #0]
	ldr	ip, [r4, #64]
	mov	r3, r3, lsr #9
	and	r3, r3, #1
	str	r3, [r4, #44]
	mov	r2, r9
	mov	r3, r1
	mov	r0, r4
	mov	r1, r6
	str	ip, [sp, #0]
	bl	submit_page_section
	cmp	r0, #0
	str	r0, [fp, #-48]
	beq	.L269
	ldr	r3, [r6, #0]
.L291:
	tst	r3, #2048
	bne	.L215
	ldr	r3, [r6, #4]
	cmp	r3, #0
	streq	r3, [r3, #0]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r6, #4]
	sub	r3, r3, #1
	str	r3, [r6, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	bne	.L215
	mov	r0, r6
	bl	__page_cache_release
	b	.L215
.L269:
	ldr	r3, [r4, #64]
	ldr	r2, [r4, #28]
	ldr	r1, [r4, #32]
	add	r3, r3, r5
	rsb	r1, r5, r1
	add	r2, r2, r5
	str	r3, [r4, #64]
	str	r2, [r4, #28]
	str	r1, [r4, #32]
	add	r7, r7, r5
.L261:
	ldr	r3, [r4, #36]
	ldr	r2, [r4, #28]
	cmp	r2, r3
	movhi	r3, #0
	strhi	r3, [r3, #0]
	ldr	r2, [r4, #28]
	ldr	r3, [r4, #36]
	cmp	r2, r3
	beq	.L217
	ldr	r3, [fp, #-44]
	cmp	r7, r3
	bcc	.L278
.L217:
	ldr	r3, [r6, #0]
	tst	r3, #2048
	bne	.L284
	ldr	r3, [r6, #4]
	cmp	r3, #0
	streq	r3, [r3, #0]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r6, #4]
	sub	r3, r3, #1
	str	r3, [r6, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	moveq	r0, r6
	bleq	__page_cache_release
.L284:
	ldr	r2, [r4, #28]
	ldr	r3, [r4, #36]
	mov	r7, #0
	cmp	r2, r3
	bcc	.L285
.L215:
	ldr	r0, [fp, #-48]
	ldmea	fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
.L293:
	.align	2
.L292:
	.word	mem_map
	.size	do_direct_IO, .-do_direct_IO
	.align	2
	.type	direct_io_worker, %function
direct_io_worker:
	@ args = 24, pretend = 0, frame = 8
	@ frame_needed = 1, uses_anonymous_args = 0
.L297:
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
	sub	fp, ip, #4
	sub	sp, sp, #8
	str	r0, [fp, #-44]
	ldr	r0, .L368
	mov	r9, r1
	ldr	r0, [r0, #4]
	mov	r1, #208
	str	r2, [fp, #-48]
	mov	sl, r3
	ldr	r8, [fp, #16]
	bl	kmem_cache_alloc
	cmp	r0, #0
	mov	r5, r0
	mov	r6, #0
	bne	.L332
	mvn	r0, #11
	ldmea	fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
.L367:
	mov	r0, r5
	bl	dio_cleanup
	b	.L340
.L332:
	ldr	r3, [r9, #16]
	mov	r4, #0
	adds	r3, r3, #1
	movne	r3, #1
	str	r3, [r0, #432]
	str	r4, [r0, #0]
	ldr	r1, [fp, #-48]
	mov	r7, r4
	str	r1, [r0, #4]
	ldr	r2, [fp, #-44]
	str	r8, [r0, #12]
	str	r2, [r0, #8]
	ldr	r3, [r1, #84]
	str	r4, [r0, #20]
	rsb	r3, r8, r3
	str	r3, [r0, #16]
	ldmib	fp, {r0-r1}
	mov	r2, r8
	bl	__ashrdi3
	ldr	r3, [fp, #12]
	str	r0, [r5, #28]
	cmp	r4, r3
	mov	r3, #1
	str	r3, [r5, #412]
	ldr	r3, [fp, #20]
	mvn	r2, #0
	str	r3, [r5, #52]
	ldr	r3, [fp, #24]
	str	r2, [r5, #64]
	str	r3, [r5, #56]
	str	r9, [r5, #428]
	str	r4, [r5, #32]
	str	r4, [r5, #116]
	str	r4, [r5, #44]
	str	r4, [r5, #48]
	str	r4, [r5, #104]
	str	r2, [r5, #60]
	str	r4, [r5, #408]
	str	r4, [r5, #436]
	str	r4, [r5, #416]
	str	r4, [r5, #420]
	str	r4, [r5, #424]
	str	r4, [r5, #24]
	bcs	.L340
	mov	r1, sl
.L338:
	ldr	r2, [r1, #4]
	ldr	r3, [r5, #24]
	ldr	r4, [fp, #12]
	add	r7, r7, #1
	add	r3, r3, r2, lsr r8
	add	r3, r3, #2
	cmp	r7, r4
	str	r3, [r5, #24]
	add	r1, r1, #8
	bcc	.L338
	mov	r7, #0
	cmp	r7, r4
	bcs	.L340
.L345:
	mov	r3, r7, asl #3
	ldr	lr, [r3, sl]
	add	r4, r3, sl
	ldr	ip, [r4, #4]
	mov	r3, lr, asl #20
	mov	r3, r3, lsr #20
	cmp	r3, #0
	add	r6, ip, r3
	ldr	r1, [r5, #28]
	mov	r3, r3, lsr r8
	mov	r2, #0
	str	r3, [r5, #40]
	movne	r3, #1
	add	r1, r1, ip, lsr r8
	str	r2, [r5, #136]
	subne	ip, r6, #4096
	strne	r3, [r5, #136]
	str	r2, [r5, #400]
	str	r2, [r5, #404]
	str	r2, [r5, #132]
	add	r3, ip, #4080
	ldr	r2, [r5, #136]
	add	r3, r3, #15
	add	r2, r2, r3, lsr #12
	str	r1, [r5, #36]
	str	r2, [r5, #136]
	mov	r0, r5
	str	lr, [r5, #140]
	bl	do_direct_IO
	ldr	r2, [r5, #28]
	ldr	r1, [r5, #36]
	ldr	r3, [r4, #4]
	rsb	r1, r2, r1
	ldr	r2, [r5, #436]
	sub	r3, r3, r1, asl r8
	add	r2, r2, r3
	cmp	r0, #0
	add	r7, r7, #1
	mov	r6, r0
	str	r2, [r5, #436]
	bne	.L367
	ldr	r1, [fp, #12]
	cmp	r7, r1
	bcc	.L345
.L340:
	mov	r0, r5
	mov	r1, #1
	bl	dio_zero_block
	ldr	r3, [r5, #116]
	cmp	r3, #0
	beq	.L346
	mov	r0, r5
	bl	dio_send_cur_page
	ldr	r1, [r5, #116]
	cmp	r6, #0
	ldr	r3, [r1, #0]
	moveq	r6, r0
	tst	r3, #2048
	bne	.L353
	ldr	r3, [r1, #4]
	cmp	r3, #0
	streq	r3, [r3, #0]
	mrs	r2, cpsr		@ local_irq_save
	orr	r3, r2, #128
	msr	cpsr_c, r3
	ldr	r3, [r1, #4]
	sub	r3, r3, #1
	str	r3, [r1, #4]
	msr	cpsr_c, r2		@ local_irq_restore

	cmp	r3, #0
	moveq	r0, r1
	bleq	__page_cache_release
.L353:
	mov	r3, #0
	str	r3, [r5, #116]
.L346:
	ldr	r3, [r5, #0]
	cmp	r3, #0
	movne	r0, r5
	blne	dio_bio_submit
.L354:
	mov	r0, r5
	bl	dio_cleanup
	ldr	r3, [r5, #432]
	cmp	r3, #0
	beq	.L355
	cmp	r6, #0
	mov	r0, r5
	ldreq	r6, [r5, #436]
	bl	finished_one_bio
	bl	blk_run_queues
	b	.L357
.L355:
	mov	r0, r5
	bl	finished_one_bio
	mov	r0, r5
	bl	dio_await_completion
	cmp	r6, #0
	bne	.L360
	subs	r6, r0, #0
	bne	.L360
	ldr	r6, [r5, #408]
	cmp	r6, #0
	bne	.L360
	ldr	r1, [r5, #436]
	cmp	r1, #0
	beq	.L360
	ldr	r2, [fp, #-44]
	ldr	r4, [fp, #-48]
	cmp	r2, #0
	add	r3, r4, #52
	ldmia	r3, {r2-r3}
	mov	r6, r1
	bne	.L360
	ldmib	fp, {r7-r8}
	adds	r0, r7, r1
	adc	r1, r8, r6, asr #31
	cmp	r1, r3
	bgt	.L363
	bne	.L360
	cmp	r0, r2
	bls	.L360
.L363:
	ldr	r8, [fp, #4]
	rsb	r6, r8, r2
.L360:
	mov	r0, r5
	ldmib	fp, {r1-r2}
	mov	r3, r6
	bl	dio_complete
	mov	r0, r5
	bl	kfree
.L357:
	mov	r0, r6
	ldmea	fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
.L369:
	.align	2
.L368:
	.word	malloc_sizes+72
	.size	direct_io_worker, .-direct_io_worker
	.align	2
	.global	blockdev_direct_IO
	.type	blockdev_direct_IO, %function
blockdev_direct_IO:
	@ args = 24, pretend = 0, frame = 16
	@ frame_needed = 1, uses_anonymous_args = 0
	mov	ip, sp
	stmfd	sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
	sub	fp, ip, #4
	sub	sp, sp, #40
	str	r2, [fp, #-52]
	ldr	lr, [r2, #84]
	mov	r5, r3
	mov	r2, #1
	cmp	r3, #0
	add	r3, fp, #8
	mov	r2, r2, asl lr
	ldmia	r3, {r6-r7}
	mvn	r3, #21
	str	r0, [fp, #-44]
	str	r1, [fp, #-48]
	sub	r2, r2, #1
	ldr	sl, [fp, #4]
	ldr	r9, [fp, #16]
	mov	r8, #0
	str	r3, [fp, #-56]
	beq	.L371
	ldr	r3, [r5, #64]
	mov	r1, #512
	ldr	ip, [r3, #36]
	cmp	ip, r8
	beq	.L373
	ldr	r3, .L397
	ldrh	r3, [ip, r3]
	cmp	r3, r8
	movne	r1, r3
.L373:
	mov	r3, r1
	mov	ip, #8
.L376:
	mov	r3, r3, lsr #1
	cmp	r3, #256
	add	ip, ip, #1
	bhi	.L376
	mov	r8, ip
.L371:
	and	r3, r6, r2
	mov	r4, #0
	orrs	r3, r3, r4
	beq	.L381
	cmp	r5, #0
	movne	lr, r8
	mov	r3, #1
	mov	r3, r3, asl lr
	sub	r2, r3, #1
	and	r3, r6, r2
	mov	r4, #0
	orrs	r3, r3, r4
	bne	.L384
.L381:
	mov	r1, #0
	cmp	r1, r9
	bcs	.L396
.L394:
	mov	r3, r1, asl #3
	ldr	r0, [r3, sl]
	add	r3, r3, sl
	tst	r0, r2
	add	r1, r1, #1
	ldr	ip, [r3, #4]
	bne	.L390
	tst	ip, r2
	beq	.L387
.L390:
	cmp	r5, #0
	movne	lr, r8
	mov	r3, #1
	mov	r3, r3, asl lr
	sub	r2, r3, #1
	tst	r0, r2
	bne	.L384
	tst	ip, r2
	bne	.L384
.L387:
	cmp	r1, r9
	bcc	.L394
.L396:
	ldr	ip, [fp, #20]
	ldr	r0, [fp, #-44]
	str	ip, [sp, #16]
	ldr	ip, [fp, #24]
	ldr	r1, [fp, #-48]
	ldr	r2, [fp, #-52]
	mov	r3, sl
	stmia	sp, {r6-r7}
	str	r9, [sp, #8]
	str	lr, [sp, #12]
	str	ip, [sp, #20]
	bl	direct_io_worker
	str	r0, [fp, #-56]
.L384:
	ldr	r0, [fp, #-56]
	ldmea	fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
.L398:
	.align	2
.L397:
	.word	398
	.size	blockdev_direct_IO, .-blockdev_direct_IO
	.section	__kcrctab,"a",%progbits
	.align	2
	.type	__kcrctab_blockdev_direct_IO, %object
	.size	__kcrctab_blockdev_direct_IO, 4
__kcrctab_blockdev_direct_IO:
	.word	__crc_blockdev_direct_IO
	.section	__ksymtab_strings,"a",%progbits
	.align	2
	.type	__kstrtab_blockdev_direct_IO, %object
	.size	__kstrtab_blockdev_direct_IO, 19
__kstrtab_blockdev_direct_IO:
	.ascii	"blockdev_direct_IO\000"
	.section	__ksymtab,"a",%progbits
	.align	2
	.type	__ksymtab_blockdev_direct_IO, %object
	.size	__ksymtab_blockdev_direct_IO, 8
__ksymtab_blockdev_direct_IO:
	.word	blockdev_direct_IO
	.word	__kstrtab_blockdev_direct_IO
	.weak	__crc_blockdev_direct_IO
	.ident	"GCC: (GNU) 3.3.2"

Attachment: arm-direct-io.s.ret
Description: Binary data


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux