2013-10-01 Joern Rennecke <joern.rennecke@embecosm.com>
[official-gcc.git] / libgcc / config / arc / gmon / profil.S
blob31b045238d41347c3da0173122c550bcc2ed4e6d
1 /* This file contains code to do profiling.
3    Copyright (C) 2007-2012 Free Software Foundation, Inc.
4    Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
5                 on behalf of Synopsys Inc.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
20 Under Section 7 of GPL version 3, you are granted additional
21 permissions described in the GCC Runtime Library Exception, version
22 3.1, as published by the Free Software Foundation.
24 You should have received a copy of the GNU General Public License and
25 a copy of the GCC Runtime Library Exception along with this program;
26 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
27 <http://www.gnu.org/licenses/>.  */
29 #include "../asm.h"
30 #include "auxreg.h"
31 /*  This file contains code to do profiling.  */
32         .weak   __profile_timer_cycles
33         .global __profile_timer_cycles
34         .set    __profile_timer_cycles, 200
36         .section .bss
37         .global __profil_offset
38         .align 4
39         .type   __profil_offset, @object
40         .size   __profil_offset, 4
41 __profil_offset:
42         .zero   4
44         .text
45         .global __dcache_linesz
46         .global __profil
47         FUNC(__profil)
48 .Lstop_profiling:
49         sr      r0,[CONTROL0]
50         j_s     [blink]
51         .balign 4
52 __profil:
53 .Lprofil:
54         breq_s  r0,0,.Lstop_profiling
55         ; r0: buf r1: bufsiz r2: offset r3: scale
56         bxor.f  r3,r3,15; scale must be 0x8000, i.e. 1/2; generate 0.
57         push_s  blink
58         lsr_s   r2,r2,1
59         mov_s   r8,r0
60         flag.ne 1       ; halt if wrong scale
61         sub_s   r0,r0,r2
62         st      r0,[__profil_offset]
63         bl      __dcache_linesz
64         pop_s   blink
65         bbit1.d r0,0,nocache
66         mov_s   r0,r8
67 #ifdef __ARC700__
68         add_s   r1,r1,31
69         lsr.f   lp_count,r1,5
70         lpne    2f
71         sr      r0,[DC_FLDL]
72         add_s   r0,r0,32
73 #else /* !__ARC700__ */
74 # FIX ME: set up loop according to cache line size
75         lr      r12,[D_CACHE_BUILD]
76         sub_s   r0,r0,16
77         sub_s   r1,r1,1
78         lsr_s   r12,r12,16
79         asr_s   r1,r1,4
80         bmsk_s  r12,r12,3
81         asr_s   r1,r1,r12
82         add.f   lp_count,r1,1
83         mov_s   r1,16
84         asl_s   r1,r1,r12
85         lpne    2f
86         add     r0,r0,r1
87         sr      r0,[DC_FLDL]
88 #endif /* __ARC700__ */
89 2:      b_s     .Lcounters_cleared
90 nocache:
91 .Lcounters_cleared:
92         lr      r1,[INT_VECTOR_BASE] ; disable timer0 interrupts
93         sr      r3,[CONTROL0]
94         sr      r3,[COUNT0]
95 0:      ld_s    r0,[pcl,1f-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF
96 0:      ld_s    r12,[pcl,1f+4-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF + 4
97         st_s    r0,[r1,24]; timer0 uses vector3
98         st_s    r12,[r1,24+4]; timer0 uses vector3
99         ;sr     10000,[LIMIT0]
100         sr      __profile_timer_cycles,[LIMIT0]
101         mov_s   r12,3   ; enable timer interrupts; count only when not halted.
102         sr      r12,[CONTROL0]
103         lr      r12,[STATUS32]
104         bset_s  r12,r12,1 ; allow level 1 interrupts
105         flag    r12
106         mov_s   r0,0
107         j_s     [blink]
108         .balign 4
109 1:      j       __profil_irq
110         ENDFUNC(__profil)
112         FUNC(__profil_irq)
113         .balign 4       ; make final jump unaligned to avoid delay penalty
114         .balign 32,0,12 ; make sure the code spans no more that two cache lines
115         nop_s
116 __profil_irq:
117         push_s  r0
118         ld      r0,[__profil_offset]
119         push_s  r1
120         lsr     r1,ilink1,2
121         push_s  r2
122         ldw.as.di r2,[r0,r1]
123         add1    r0,r0,r1
124         ld_s    r1,[sp,4]
125         add_s   r2,r2,1
126         bbit1   r2,16,nostore
127         stw.di  r2,[r0]
128 nostore:ld.ab   r2,[sp,8]
129         pop_s   r0
130         j.f     [ilink1]
131         ENDFUNC(__profil_irq)
133 ; could save one cycle if the counters were allocated at link time and
134 ; the contents of __profil_offset were pre-computed at link time, like this:
135 #if 0
136 ; __profil_offset needs to be PROVIDEd as __profile_base-text/4
137         .global __profil_offset
138         .balign 4
139 __profil_irq:
140         push_s  r0
141         lsr     r0,ilink1,2
142         add1    r0,__profil_offset,r0
143         push_s  r1
144         ldw.di  r1,[r0]
147         add_s   r1,r1,1
148         bbit1   r1,16,nostore
149         stw.di  r1,[r0]
150 nostore:pop_s   r1
151         pop_s   r0
152         j       [ilink1]
153 #endif /* 0 */