UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor yosmany325
Visitor
8,713 Views
Registered: ‎03-04-2016

Why is Microblaze Code Size too big?

Jump to solution

Hello everyone!

 

I would like to know how I can reduce the size of the executable of my system. Currently I'm developing an application for MicroBlaze processor but with almost no code the executable size is too big. What I have done to reduce the fina size is:

 

* Disable the use of startup files provided by Xilinx (-nostartfiles, -nodefaultlibs, -nostdlib). 

* Inclusion of a very simplified version of crt0.s as below:

 

.globl _start
.section .vectors.reset, "ax"
.align 2
.ent _start
.type _start, @function
_start:
brai _start1
.end _start

.section .vectors.sw_exception, "ax"
.align 2


_vector_sw_exception:
brai _exception_handler

.section .vectors.interrupt, "ax"
.align 2


_vector_interrupt:
brai _interrupt_handler

.section .vectors.hw_exception, "ax"
.align 2


_vector_hw_exception:
brai _hw_exception_handler

.section .text
.globl _start1
.align 2


.ent _start1
.type _start1, @function
_start1:
la r13, r0, _SDA_BASE_ /* Set the Small Data Anchors and the stack pointer */
la r2, r0, _SDA2_BASE_
la r1, r0, _stack-16 /* 16 bytes (4 words are needed by crtinit for args and link reg */

/*brlid r15, _crtinit /* Initialize BSS and run program */
/*nop*/

bri 0
/* Control does not reach here */
.end _start1

 

* Modification of linker script as follows:

 

_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x400;

 

/* Define Memories in the system */

MEMORY
{
ilmb_cntlr_dlmb_cntlr : ORIGIN = 0x00000050, LENGTH = 0x00003FB0
}

 

/* Specify the default entry point to the program */

ENTRY(_start)

 

/* Define the sections, and where they are mapped in memory */

SECTIONS
{
.vectors.reset 0x00000000 : {
KEEP (*(.vectors.reset))
}

 

.vectors.sw_exception 0x00000008 : {
KEEP (*(.vectors.sw_exception))
}

.vectors.interrupt 0x00000010 : {
KEEP (*(.vectors.interrupt))
}

 

.vectors.hw_exception 0x00000020 : {
KEEP (*(.vectors.hw_exception))
}

 

.text : {
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
} > ilmb_cntlr_dlmb_cntlr

 

 

.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.sdata2 : {
. = ALIGN(8);
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
. = ALIGN(8);
__sdata2_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.data : {
. = ALIGN(4);
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
__data_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.got : {
*(.got)
} > ilmb_cntlr_dlmb_cntlr

 

.got1 : {
*(.got1)
} > ilmb_cntlr_dlmb_cntlr

 

.got2 : {
*(.got2)
} > ilmb_cntlr_dlmb_cntlr

 

.eh_frame : {
*(.eh_frame)
} > ilmb_cntlr_dlmb_cntlr

.jcr : {
*(.jcr)
} > ilmb_cntlr_dlmb_cntlr

.gcc_except_table : {
*(.gcc_except_table)
} > ilmb_cntlr_dlmb_cntlr

 

.sdata : {
. = ALIGN(8);
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.sbss (NOLOAD) : {
. = ALIGN(4);
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
. = ALIGN(8);
__sbss_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.bss (NOLOAD) : {
. = ALIGN(4);
__bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
__bss_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );

_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );

 

/* Generate Stack and Heap definitions */

 

.heap (NOLOAD) : {
. = ALIGN(8);
_heap = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
} > ilmb_cntlr_dlmb_cntlr

 

.stack (NOLOAD) : {
_stack_end = .;
. += _STACK_SIZE;
. = ALIGN(8);
_stack = .;
__stack = _stack;
} > ilmb_cntlr_dlmb_cntlr

 

_end = .;
}

 

* Stack/Heap Size Reduction to 0x100 bytes (from 0x400)

 

After these efforts the results keep too big for almost no program at all. After compilation the size reported is:

 

Invoking: MicroBlaze Print Size
mb-size BareMetal.elf |tee "BareMetal.elf.size"
text data bss     dec    hex    filename
500 88    2052  2640  a50    BareMetal.elf

 

After performing a mb-objdump -D BareMetal.elf the results show the inclusion of Interrupt handling routines and much more, not desired in this case. 

 

Did anyone knows any way to change this behavior? The following text attached is the dump obtained. 

 

Thanks in advance for your time. Yosmany. 

 

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Xilinx Employee
Xilinx Employee
15,580 Views
Registered: ‎08-06-2007

Re: Why is Microblaze Code Size too big?

Jump to solution

Hi,

 

1. What features have you enabled on the MicroBlaze?

    If you don't enable certain hardware feature, the compiler will need to generate code for solving the operations.

    Ex. If you don't have barrel shifter enabled and need to shift inside your code, the compiler will need to insert multiple single-bit shift instructions instead of just one barrel shifter instructions.

To minimize code size, enable as many hardware features as you can that impacts code size.

These are:

- barrel shifter

- hardware divider (if you are using division)

- multiplication

- pattern compare instructions

- floating point (if you use float)

 

2. Compiler options

Make sure that all implemented hardware features (above) is enabled for the compiler to make sure it generates code using it.

Compile for area (-Os)

 

3. Make sure that the linker will remove all unreference function code and data

This is done with first tagging all functions and data references, compiler option (-ffunction-sections, -fdata-sections) and then tell the linker to remove all unreference functions and data with the option (-Wl,--gc-sections)

If you are using SDK, these options exists as options on the C/C++ build settings

This can have drastic impacts on the code size.

 

4. To make sure that the linker removes all unnecessary IMM instructions, make sure that you remove the norelax option for the linker.

Exists as an option in SDK C/C++ build settings.

 

5. If you are not using interrupts, just create a dummy void __interrupt_handler function

 

If you apply these tricks, I would be very interested to see what the code size ended up at.

 

Göran

 

View solution in original post

0 Kudos
2 Replies
Highlighted
Xilinx Employee
Xilinx Employee
15,581 Views
Registered: ‎08-06-2007

Re: Why is Microblaze Code Size too big?

Jump to solution

Hi,

 

1. What features have you enabled on the MicroBlaze?

    If you don't enable certain hardware feature, the compiler will need to generate code for solving the operations.

    Ex. If you don't have barrel shifter enabled and need to shift inside your code, the compiler will need to insert multiple single-bit shift instructions instead of just one barrel shifter instructions.

To minimize code size, enable as many hardware features as you can that impacts code size.

These are:

- barrel shifter

- hardware divider (if you are using division)

- multiplication

- pattern compare instructions

- floating point (if you use float)

 

2. Compiler options

Make sure that all implemented hardware features (above) is enabled for the compiler to make sure it generates code using it.

Compile for area (-Os)

 

3. Make sure that the linker will remove all unreference function code and data

This is done with first tagging all functions and data references, compiler option (-ffunction-sections, -fdata-sections) and then tell the linker to remove all unreference functions and data with the option (-Wl,--gc-sections)

If you are using SDK, these options exists as options on the C/C++ build settings

This can have drastic impacts on the code size.

 

4. To make sure that the linker removes all unnecessary IMM instructions, make sure that you remove the norelax option for the linker.

Exists as an option in SDK C/C++ build settings.

 

5. If you are not using interrupts, just create a dummy void __interrupt_handler function

 

If you apply these tricks, I would be very interested to see what the code size ended up at.

 

Göran

 

View solution in original post

0 Kudos
Visitor yosmany325
Visitor
8,207 Views
Registered: ‎03-04-2016

Re: Why is Microblaze Code Size too big?

Jump to solution

Hello Goran, first, I would like to thank you for your answer and apologize the delay to reply. I tested what you suggested and in fact the code size decreased. Currently I´m not working on this project but as soon as I can resume my work I will provide more details. Thank you very much. 

0 Kudos