URL
https://opencores.org/ocsvn/ao486/ao486/trunk
Subversion Repositories ao486
[/] [ao486/] [trunk/] [syn/] [soc/] [firmware/] [exe_bsp/] [HAL/] [src/] [alt_mcount.S] - Rev 2
Compare with Previous | Blame | View Log
/******************************************************************************* ** License Agreement ** ** Copyright (c) 2003-2010 Altera Corporation, San Jose, California, USA. ** All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and associated documentation files (the "Software"), ** to deal in the Software without restriction, including without limitation ** the rights to use, copy, modify, merge, publish, distribute, sublicense, ** and/or sell copies of the Software, and to permit persons to whom the ** Software is furnished to do so, subject to the following conditions: ** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ** DEALINGS IN THE SOFTWARE. ** ** This agreement shall be governed in all respects by the laws of the State ** of California and by the laws of the United States of America. ** *******************************************************************************//* mcount or _mcount is inserted by GCC before the function prologue of every* function when a program is compiled for profiling. At the start of mcount,* we guarantee that:* ra = self_pc (an address in the function which called mcount)* r8 = from_pc (an address in the function which called mcount's caller)** Because this is always called at the start of a function we can corrupt* r2,r3 and r11-r15. We must not corrupt r4-r7 (because they might contain* function arguments for the instrumented function) or r8 (which holds ra* for the instrumented function).*/.global __mcount_fn_head.global mcount/* _mcount is used by gcc4 */.global _mcount_mcount:mcount:/* Use a hash to speed up locating fn_entry. We use bits 5 upwards to choose* the bucket because bits 1:0 will always be 0, and because the distribution* of values for bits 4:2 won't be even (aligning on cache line boundaries* will skew it). Higher bits should be fairly random.*//* fn_head = mcount_fn_head + (((unsigned int)self_pc >> 5) & (HASH_BUCKETS - 1)); */srli r2, ra, 3movhi r3, %hiadj(__mcount_fn_head)addi r3, r3, %lo(__mcount_fn_head)andi r2, r2, 0xFCadd r11, r2, r3/* The fast case is where we have already allocated a function arc, and so* also a function pointer.*//* First find the function being called (using self_pc) */mov r10, r110:ldw r10, 0(r10)beq r10, zero, .Lnew_arcldw r2, 4(r10)bne r2, ra, 0b/* Found a function entry for this PC. Now look for an arc with a matching* from_pc value. There will always be at least one arc. */ldw r3, 8(r10)0:ldw r2, 4(r3)beq r2, r8, .Lfound_arcldw r3, 0(r3)bne r3, zero, 0b.Lnew_arc:addi sp, sp, -24.LCFI0:stw ra, 0(sp)stw r4, 4(sp)stw r5, 8(sp)stw r6, 12(sp)stw r7, 16(sp)stw r8, 20(sp).LCFI1:/* __mcount_record(orig_ra, orig_r8, fn_entry, *fn_head); */mov r4, ramov r5, r8mov r6, r10mov r7, r11call __mcount_record/* restore registers from the stack */ldw ra, 0(sp)ldw r4, 4(sp)ldw r5, 8(sp)ldw r6, 12(sp)ldw r7, 16(sp)ldw r8, 20(sp)addi sp, sp, 24.LCFI2:ret.Lfound_arc:/* We've found the correct arc record. Increment the count and return */ldw r2, 8(r3)addi r2, r2, 1stw r2, 8(r3)ret.Lmcount_end:/** Dwarf2 debug information for the function. This provides GDB with the* information it needs to backtrace out of this function.*/.section .debug_frame,"",@progbits.LCIE:.4byte 2f - 1f /* Length */1:.4byte 0xffffffff /* CIE id */.byte 0x1 /* Version */.string "" /* Augmentation */.uleb128 0x1 /* Code alignment factor */.sleb128 -4 /* Data alignment factor */.byte 0x1f /* Return address register */.byte 0xc /* Define CFA */.uleb128 0x1b /* Register 27 (sp) */.uleb128 0x0 /* Offset 0 */.align 2 /* Padding */2:.LFDE_mcount:.4byte 2f - 1f /* Length */1:.4byte .LCIE /* Pointer to CIE */.4byte mcount /* Start of table entry */.4byte .Lmcount_end - mcount /* Size of table entry */.byte 0x4 /* Advance location */.4byte .LCFI0 - mcount /* to .LCFI0 */.byte 0xe /* Define CFA offset */.uleb128 24 /* to 24 */.byte 0x4 /* Advance location */.4byte .LCFI1 - .LCFI0 /* to .LCFI1 */.byte 0x9f /* Store ra */.uleb128 0x6 /* at CFA-24 */.byte 0x84 /* Store r4 */.uleb128 0x5 /* at CFA-20 */.byte 0x85 /* Store r5 */.uleb128 0x4 /* at CFA-16 */.byte 0x86 /* Store r6 */.uleb128 0x3 /* at CFA-12 */.byte 0x87 /* Store r7 */.uleb128 0x2 /* at CFA-8 */.byte 0x88 /* Store r8 */.uleb128 0x1 /* at CFA-4 */.byte 0x4 /* Advance location */.4byte .LCFI2 - .LCFI1 /* to .LCFI2 */.byte 0xe /* Define CFA offset */.uleb128 0 /* to 0 */.byte 0x8 /* Same value */.uleb128 31 /* for ra */.byte 0x8 /* Same value */.uleb128 4 /* for r4 */.byte 0x8 /* Same value */.uleb128 5 /* for r5 */.byte 0x8 /* Same value */.uleb128 6 /* for r6 */.byte 0x8 /* Same value */.uleb128 7 /* for r7 */.byte 0x8 /* Same value */.uleb128 8 /* for r8 */.align 22:
