regtest: callgrind bug497723 again, order of output can vary
[valgrind.git] / exp-bbv / tests / arm-linux / ll.S
blob231cd89b54fce71b0cfc09202db7a70ca758dfaf
2 #  linux_logo in ARM assembly language
3 #    based on the code from ll_asm-0.41
5 #  By Vince Weaver <vince _at_ deater.net>
7 # Modified to remove non-deterministic system calls
8 # And to avoid reading from /proc
10 .include "logo.include"
12 # offsets into the results returned by the uname syscall
13 .equ U_SYSNAME,0
14 .equ U_NODENAME,65
15 .equ U_RELEASE,65*2
16 .equ U_VERSION,(65*3)
17 .equ U_MACHINE,(65*4)
18 .equ U_DOMAINNAME,65*5
20 # offset into the results returned by the sysinfo syscall
21 .equ S_TOTALRAM,16
23 # Sycscalls
24 .equ SYSCALL_EXIT,      1
25 .equ SYSCALL_WRITE,     4
28 .equ STDIN,0
29 .equ STDOUT,1
30 .equ STDERR,2
32         .globl _start   
33 _start:
34         ldr     r11,data_addr
35         ldr     r12,bss_addr
37         #=========================
38         # PRINT LOGO
39         #=========================
41 # LZSS decompression algorithm implementation
42 # by Stephan Walter 2002, based on LZSS.C by Haruhiko Okumura 1989
43 # optimized some more by Vince Weaver
45         ldr     r1,out_addr             @ buffer we are printing to
47         mov     r2,#(N-F)               @ R
49         add     r3,r11,#(logo-data_begin)
50                                         @ r3 points to logo data
51         ldr     r8,logo_end_addr
52                                         @ r8 points to logo end
53         ldr     r9,text_addr            @ r9 points to text buf
55 decompression_loop:
56         ldrb    r4,[r3],#+1             @ load a byte, increment pointer        
58         mov     r5,#0xff                @ load top as a hackish 8-bit counter
59         orr     r5,r4,r5,LSL #8         @ shift 0xff left by 8 and or in the byte we loaded
61 test_flags:
62         cmp     r3,r8           @ have we reached the end?
63         bge     done_logo       @ if so, exit
65         lsrs    r5,#1           @ shift bottom bit into carry flag
66         bcs     discrete_char   @ if set, we jump to discrete char
68 offset_length:
69         ldrb    r0,[r3],#+1     @ load a byte, increment pointer
70         ldrb    r4,[r3],#+1     @ load a byte, increment pointer        
71                                 @ we can't load halfword as no unaligned loads on arm
73         orr     r4,r0,r4,LSL #8 @ merge back into 16 bits
74                                 @ this has match_length and match_position
76         mov     r7,r4           @ copy r4 to r7
77                                 @ no need to mask r7, as we do it
78                                 @ by default in output_loop
80         mov     r0,#(THRESHOLD+1)
81         add     r6,r0,r4,LSR #(P_BITS)
82                                 @ r6 = (r4 >> P_BITS) + THRESHOLD + 1
83                                 @                       (=match_length)
85 output_loop:
86         ldr     r0,pos_mask             @ urgh, can't handle simple constants
87         and     r7,r7,r0                @ mask it
88         ldrb    r4,[r9,r7]              @ load byte from text_buf[]
89         add     r7,r7,#1                @ advance pointer in text_buf
91 store_byte:
92         strb    r4,[r1],#+1             @ store a byte, increment pointer
93         strb    r4,[r9,r2]              @ store a byte to text_buf[r]
94         add     r2,r2,#1                @ r++
95         mov     r0,#(N)
96         sub     r0,r0,#1                @ grrr no way to get this easier
97         and     r2,r2,r0                @ mask r
99         subs    r6,r6,#1                @ decement count
100         bne     output_loop             @ repeat until k>j
102         tst     r5,#0xff00              @ are the top bits 0?
103         bne     test_flags              @ if not, re-load flags
105         b       decompression_loop
107 discrete_char:
108         ldrb    r4,[r3],#+1             @ load a byte, increment pointer                
109         mov     r6,#1                   @ we set r6 to one so byte
110                                         @ will be output once
112         b       store_byte              @ and store it
115 # end of LZSS code
117 done_logo:
118         ldr     r1,out_addr             @ buffer we are printing to
120         bl      write_stdout            @ print the logo
122         #==========================
123         # PRINT VERSION
124         #==========================
125 first_line:
127         mov     r0,#0
128         add     r1,r11,#(uname_info-data_begin)
129                                                 @ os-name from uname "Linux"
131         ldr     r10,out_addr                    @ point r10 to out_buffer
133         bl      strcat                          @ call strcat
135         
136         add     r1,r11,#(ver_string-data_begin) @ source is " Version "
137         bl      strcat                          @ call strcat
139         add     r1,r11,#((uname_info-data_begin)+U_RELEASE)
140                                                 @ version from uname, ie "2.6.20"
141         bl      strcat                          @ call strcat
142         
143         add     r1,r11,#(compiled_string-data_begin)
144                                                 @ source is ", Compiled "
145         bl      strcat                          @  call strcat
147         add     r1,r11,#((uname_info-data_begin)+U_VERSION)
148                                                 @ compiled date
149         bl      strcat                          @ call strcat
151         mov     r3,#0xa 
152         strb    r3,[r10],#+1            @ store a linefeed, increment pointer
153         strb    r0,[r10],#+1            @ NUL terminate, increment pointer
154         
155         bl      center_and_print        @ center and print
157         @===============================
158         @ Middle-Line
159         @===============================
160 middle_line:            
161         @=========
162         @ Load /proc/cpuinfo into buffer
163         @=========
165         ldr     r10,out_addr            @ point r10 to out_buffer
166         
167         @=============
168         @ Number of CPUs
169         @=============
170 number_of_cpus:
172         add     r1,r11,#(one-data_begin)
173                                         # cheat.  Who has an SMP arm?
174         bl      strcat
176         @=========
177         @ MHz
178         @=========
179 print_mhz:
180         
181         @ the arm system I have does not report MHz
183         @=========
184         @ Chip Name
185         @=========
186 chip_name:      
187         mov     r0,#'s'
188         mov     r1,#'o'
189         mov     r2,#'r'
190         mov     r3,#' '
191         bl      find_string
192                                         @ find 'sor\t: ' and grab up to ' '
194         add     r1,r11,#(processor-data_begin)
195                                         @ print " Processor, "
196         bl      strcat  
197         
198         @========
199         @ RAM
200         @========
201         
202         
203         ldr     r3,[r11,#((sysinfo_buff-data_begin)+S_TOTALRAM)]
204                                         @ size in bytes of RAM
205         movs    r3,r3,lsr #20           @ divide by 1024*1024 to get M
206         adc     r3,r3,#0                @ round
208         mov     r0,#1
209         bl num_to_ascii
210         
211         add     r1,r11,#(ram_comma-data_begin)
212                                         @ print 'M RAM, '
213         bl      strcat                  @ call strcat
214         
216         @========
217         @ Bogomips
218         @========
220         mov     r0,#'I'
221         mov     r1,#'P'
222         mov     r2,#'S'
223         mov     r3,#'\n'
224         bl      find_string
226         add     r1,r11,#(bogo_total-data_begin)
227         bl      strcat                  @ print bogomips total
228         
229         bl      center_and_print        @ center and print
231         #=================================
232         # Print Host Name
233         #=================================
234 last_line:
235         ldr     r10,out_addr            @ point r10 to out_buffer       
236         
237         add     r1,r11,#((uname_info-data_begin)+U_NODENAME)
238                                         @ host name from uname()
239         bl      strcat                  @ call strcat
240         
241         bl      center_and_print        @ center and print
243         add     r1,r11,#(default_colors-data_begin)
244                                         @ restore colors, print a few linefeeds
245         bl      write_stdout
246         
248         @================================
249         @ Exit
250         @================================
251 exit:
252         mov     r0,#0                           @ result is zero
253         mov     r7,#SYSCALL_EXIT
254         swi     0x0                             @ and exit
257         @=================================
258         @ FIND_STRING 
259         @=================================
260         @ r0,r1,r2 = string to find
261         @ r3 = char to end at
262         @ r5 trashed
263 find_string:
264         ldr     r7,disk_addr            @ look in cpuinfo buffer
265 find_loop:
266         ldrb    r5,[r7],#+1             @ load a byte, increment pointer        
267         cmp     r5,r0                   @ compare against first byte
268         ldrb    r5,[r7]                 @ load next byte
269         cmpeq   r5,r1                   @ if first byte matched, comp this one
270         ldrb    r5,[r7,#+1]             @ load next byte 
271         cmpeq   r5,r2                   @ if first two matched, comp this one
272         beq     find_colon              @ if all 3 matched, we are found
273         
274         cmp     r5,#0                   @ are we at EOF?
275         beq     done                    @ if so, done
277         b       find_loop
278         
279 find_colon:
280         ldrb    r5,[r7],#+1             @ load a byte, increment pointer
281         cmp     r5,#':'
282         bne     find_colon              @ repeat till we find colon
284         add     r7,r7,#1                @ skip the space
285                 
286 store_loop:
287         ldrb    r5,[r7],#+1             @ load a byte, increment pointer
288         strb    r5,[r10],#+1            @ store a byte, increment pointer       
289         cmp     r5,r3
290         bne     store_loop
291         
292 almost_done:
293         mov     r0,#0
294         strb    r0,[r10],#-1            @ replace last value with NUL
296 done:
297         bx      r14                     @ return
299         #================================
300         # strcat
301         #================================
302         # value to cat in r1
303         # output buffer in r10
304         # r3 trashed
305 strcat:
306         ldrb    r3,[r1],#+1             @ load a byte, increment pointer 
307         strb    r3,[r10],#+1            @ store a byte, increment pointer
308         cmp     r3,#0                   @ is it zero?
309         bne     strcat                  @ if not loop
310         sub     r10,r10,#1              @ point to one less than null
311         bx      r14                     @ return
312         
314         #==============================
315         # center_and_print
316         #==============================
317         # string to center in at output_buffer
319 center_and_print:
321         stmfd   SP!,{LR}                @ store return address on stack
323         add     r1,r11,#(escape-data_begin)
324                                         @ we want to output ^[[
325         bl      write_stdout
326                 
327 str_loop2:                              
328         ldr     r2,out_addr             @ point r2 to out_buffer
329         sub     r2,r10,r2               @ get length by subtracting
331         rsb     r2,r2,#81               @ reverse subtract!  r2=81-r2
332                                         @ we use 81 to not count ending \n
334         bne     done_center             @ if result negative, don't center
335         
336         lsrs    r3,r2,#1                @ divide by 2
337         adc     r3,r3,#0                @ round?
339         mov     r0,#0                   @ print to stdout
340         bl      num_to_ascii            @ print number of spaces
342         add     r1,r11,#(C-data_begin)
343                                         @ we want to output C
344         bl      write_stdout
346 done_center:
347         ldr     r1,out_addr             @ point r1 to out_buffer
348         ldmfd   SP!,{LR}                @ restore return address from stack
350         #================================
351         # WRITE_STDOUT
352         #================================
353         # r1 has string
354         # r0,r2,r3 trashed
355 write_stdout:
356         mov     r2,#0                           @ clear count
358 str_loop1:
359         add     r2,r2,#1
360         ldrb    r3,[r1,r2]
361         cmp     r3,#0
362         bne     str_loop1                       @ repeat till zero
364 write_stdout_we_know_size:      
365         mov     r0,#STDOUT                      @ print to stdout
366         mov     r7,#SYSCALL_WRITE
367         swi     0x0                             @ run the syscall
368         bx      r14                             @ return
370         
371         @#############################
372         @ num_to_ascii
373         @#############################
374         @ r3 = value to print
375         @ r0 = 0=stdout, 1=strcat
376         
377 num_to_ascii:
378         stmfd   SP!,{r10,LR}            @ store return address on stack
379         add     r10,r12,#((ascii_buffer-bss_begin))
380         add     r10,r10,#10
381                                         @ point to end of our buffer
383         mov     r4,#10          @ we'll be dividing by 10
384 div_by_10:
385         bl      divide          @ Q=r7,$0, R=r8,$1
386         add     r8,r8,#0x30     @ convert to ascii
387         strb    r8,[r10],#-1    @ store a byte, decrement pointer       
388         adds    r3,r7,#0        @ move Q in for next divide, update flags
389         bne     div_by_10       @ if Q not zero, loop
390         
391 write_out:
392         add     r1,r10,#1       @ adjust pointer
393         ldmfd   SP!,{r10,LR}    @ restore return address from stack
394         
395         cmp     r0,#0
396         bne     strcat          @ if 1, strcat
397         
398         b write_stdout          @ else, fallthrough to stdout
400         
401         @===================================================
402         @ Divide - because ARM has no hardware int divide
403         @ yes this is an awful algorithm, but simple
404         @  and uses few registers
405         @==================================================
406         @ r3=numerator   r4=denominator
407         @ r7=quotient    r8=remainder
408         @ r5=trashed
409 divide:
411         mov     r7,#0           @ zero out quotient
412 divide_loop:
413         mul     r5,r7,r4        @ multiply Q by denominator
414         add     r7,r7,#1        @ increment quotient
415         cmp     r5,r3           @ is it greater than numerator?
416         ble     divide_loop     @ if not, loop
417         sub     r7,r7,#2        @ otherwise went too far, decrement
418                                 @ and done
419         
420         mul     r5,r7,r4        @ calculate remainder
421         sub     r8,r3,r5        @ R=N-(Q*D)
422         bx      r14             @ return
424         
425 bss_addr:       .word bss_begin
426 data_addr:      .word data_begin
427 out_addr:       .word out_buffer
428 disk_addr:      .word disk_buffer
429 logo_end_addr:  .word logo_end
430 pos_mask:       .word ((POSITION_MASK<<8)+0xff)
431 text_addr:      .word text_buf
432                                                         
433 #===========================================================================
434 #       section .data
435 #===========================================================================
436 .data
437 data_begin:
438 ver_string:     .ascii  " Version \0"
439 compiled_string:        .ascii  ", Compiled \0"
440 processor:      .ascii  " Processor, \0"
441 ram_comma:      .ascii  "M RAM, \0"
442 bogo_total:     .ascii  " Bogomips Total\n\0"
444 default_colors: .ascii "\033[0m\n\n\0"
445 escape:         .ascii "\033[\0"
446 C:              .ascii "C\0"
448 one:    .ascii  "One \0"
450 uname_info:
451 .ascii "Linux\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
452 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
453 .ascii "lindt\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
454 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
455 .ascii "2.6.32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
456 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
457 .ascii "#1 Wed May 13 15:51:54 UTC 2009\0"
458 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
459 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
460 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
461 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
462 .ascii "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
465 disk_buffer:
466 .ascii "Processor   : Feroceon 88FR131 rev 1 (v5l)\n"
467 .ascii "BogoMIPS    : 1192.75\n"
468 .ascii "Features    : swp half thumb fastmult edsp \n"
469 .ascii "CPU implementer   : 0x56\n"
470 .ascii "CPU architecture: 5TE\n"
471 .ascii "CPU variant       : 0x2\n"
472 .ascii "CPU part          : 0x131\n"
473 .ascii "CPU revision      : 1\n"
474 .ascii "\n"
475 .ascii "Hardware          : Marvell SheevaPlug Reference Board\n"
476 .ascii "Revision          : 0000\n"
477 .ascii "Serial              : 0000000000000000\n\0"
480 sysinfo_buff:
481 .long 0,0,0,0,512*1024*1024,0,0,0
483 .include        "logo.lzss_new"
486 #============================================================================
487 #       section .bss
488 #============================================================================
489 .bss
490 bss_begin:
491 .lcomm ascii_buffer,10
492 .lcomm  text_buf, (N+F-1)
493 .lcomm  out_buffer,16384