summaryrefslogtreecommitdiff
path: root/arch/arm/boot/compressed/ll_char_wr.S
blob: 8517c8606b4a7f1bafabd39556b8aa2390910bc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 *  linux/arch/arm/lib/ll_char_wr.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.
 *
 *  Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
 *
 *  10-04-96	RMK	Various cleanups & reduced register usage.
 *  08-04-98	RMK	Shifts re-ordered
 */

@ Regs: [] = corruptible
@       {} = used
@       () = do not use

#include <linux/linkage.h>
#include <asm/assembler.h>
	.text

LC0:	.word	LC0
	.word	bytes_per_char_h
	.word	video_size_row
	.word	acorndata_8x8
	.word	con_charconvtable

/*
 * r0 = ptr
 * r1 = char
 * r2 = white
 */
ENTRY(ll_write_char)
	stmfd	sp!, {r4 - r7, lr}
@
@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
@
	/*
	 * calculate offset into character table
	 */
	mov	r1, r1, lsl #3
	/*
	 * calculate offset required for each row.
	 */
	adr	ip, LC0
	ldmia	ip, {r3, r4, r5, r6, lr}
	sub	ip, ip, r3
	add	r6, r6, ip
	add	lr, lr, ip
	ldr	r4, [r4, ip]
	ldr	r5, [r5, ip]
	/*
	 * Go to resolution-dependent routine...
	 */
	cmp	r4, #4
	blt	Lrow1bpp
	add	r0, r0, r5, lsl #3		@ Move to bottom of character
	orr	r1, r1, #7
	ldrb	r7, [r6, r1]
	teq	r4, #8
	beq	Lrow8bpplp
@
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
@
Lrow4bpplp:
	ldr	r7, [lr, r7, lsl #2]
	mul	r7, r2, r7
	sub	r1, r1, #1			@ avoid using r7 directly after
	str	r7, [r0, -r5]!
	ldrb	r7, [r6, r1]
	ldr	r7, [lr, r7, lsl #2]
	mul	r7, r2, r7
	tst	r1, #7				@ avoid using r7 directly after
	str	r7, [r0, -r5]!
	subne	r1, r1, #1
	ldrneb	r7, [r6, r1]
	bne	Lrow4bpplp
	ldmfd	sp!, {r4 - r7, pc}

@
@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
@
Lrow8bpplp:
	mov	ip, r7, lsr #4
	ldr	ip, [lr, ip, lsl #2]
	mul	r4, r2, ip
	and	ip, r7, #15			@ avoid r4
	ldr	ip, [lr, ip, lsl #2]		@ avoid r4
	mul	ip, r2, ip			@ avoid r4
	sub	r1, r1, #1			@ avoid ip
	sub	r0, r0, r5			@ avoid ip
	stmia	r0, {r4, ip}
	ldrb	r7, [r6, r1]
	mov	ip, r7, lsr #4
	ldr	ip, [lr, ip, lsl #2]
	mul	r4, r2, ip
	and	ip, r7, #15			@ avoid r4
	ldr	ip, [lr, ip, lsl #2]		@ avoid r4
	mul	ip, r2, ip			@ avoid r4
	tst	r1, #7				@ avoid ip
	sub	r0, r0, r5			@ avoid ip
	stmia	r0, {r4, ip}
	subne	r1, r1, #1
	ldrneb	r7, [r6, r1]
	bne	Lrow8bpplp
	ldmfd	sp!, {r4 - r7, pc}

@
@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
@
Lrow1bpp:
	add	r6, r6, r1
	ldmia	r6, {r4, r7}
	strb	r4, [r0], r5
	mov	r4, r4, lsr #8
	strb	r4, [r0], r5
	mov	r4, r4, lsr #8
	strb	r4, [r0], r5
	mov	r4, r4, lsr #8
	strb	r4, [r0], r5
	strb	r7, [r0], r5
	mov	r7, r7, lsr #8
	strb	r7, [r0], r5
	mov	r7, r7, lsr #8
	strb	r7, [r0], r5
	mov	r7, r7, lsr #8
	strb	r7, [r0], r5
	ldmfd	sp!, {r4 - r7, pc}

	.bss
ENTRY(con_charconvtable)
	.space	1024