I'm trying to understand the disassembly of this simple function, as I'm trying to optimize some critical sections of my application.
void dummy2(uint32_t* pointer)
{
pointer[0] = 1;
}
produces:
0.0: ( 10.0ns) 0x412f8 dummy2 + 0 { sub (3r) r1, r0, r1 ; dualentsp (u6) 0x0 }
10.0: ( 10.0ns) 0x412fc dummy2 + 4 { mkmsk (rus) r3, 0x2 ; nop (0r) }
20.0: ( 10.0ns) 0x41300 dummy2 + 8 { lsu (3r) r3, r2, r3 ; nop (0r) }
30.0: ( 10.0ns) 0x41304 dummy2 + 12 bt (lru6) r3, 0x2
40.0: ( 10.0ns) 0x41308 dummy2 + 16 { sub (2rus) r2, r2, 0x3 ; nop (0r) }
50.0: ( 10.0ns) 0x4130c dummy2 + 20 bu (lu6) 0x1
60.0: ( 10.0ns) 0x41314 dummy2 + 28 { lsu (3r) r1, r1, r2 ; nop (0r) }
70.0: ( 10.0ns) 0x41318 dummy2 + 32 { ecallf (1r) r1 ; nop (0r) }
80.0: ( 10.0ns) 0x4131c dummy2 + 36 { mkmsk (rus) r1, 0x1 ; nop (0r) }
90.0: ( 10.0ns) 0x41320 dummy2 + 40 { nop (0r) ; stw (2rus) r1, r0[0x0] }
100.0: ( 10.0ns) 0x41324 dummy2 + 44 { nop (0r) ; retsp (u6) 0x0 }
Why does such a simple store operation require calls to sub, mkmsk, and bt? This seems like overkill.
Thanks for the help!
-Tim
Crazy disassembly
-
- Junior Member
- Posts: 4
- Joined: Sat Jan 07, 2017 10:39 pm
-
- XCore Addict
- Posts: 169
- Joined: Fri Oct 23, 2015 10:23 am
Hi
As you are using dual issue and a safe pointer there is a fair amount of extra boiler plating.
I would advise using -Os by default and setting the [[dual_issue]] attribute only on functions that the xta shows up as red (there is also a [[single_issue]] attribute).
If you use safe pointers where the compiler can deduce usage (e.g. in static functions), the compiler can check for out of bound errors at compile time.
In this case, the compiler is emitting code to check the validity of the pointer dereferencing.
If you use unsafe (normal) pointers the assembly produced is more compact viz:
[[dual_issue]] unsafe static void dummy2(unsigned int* unsafe pointer) {
pointer[0] = 1;
}
In dual issue, 3x 32bit instructions (with no-op padding)
In single issue, 4x 16bit instructions.
robert
As you are using dual issue and a safe pointer there is a fair amount of extra boiler plating.
I would advise using -Os by default and setting the [[dual_issue]] attribute only on functions that the xta shows up as red (there is also a [[single_issue]] attribute).
If you use safe pointers where the compiler can deduce usage (e.g. in static functions), the compiler can check for out of bound errors at compile time.
In this case, the compiler is emitting code to check the validity of the pointer dereferencing.
If you use unsafe (normal) pointers the assembly produced is more compact viz:
[[dual_issue]] unsafe static void dummy2(unsigned int* unsafe pointer) {
pointer[0] = 1;
}
In dual issue, 3x 32bit instructions (with no-op padding)
Code: Select all
dummy2:
.issue_mode dual
{
mkmsk r1, 1
dualentsp 0 // We may be called from single-issue code.
}
{
nop
stw r1, r0[0]
}
{
nop
retsp 0
}
Code: Select all
dummy2:
.issue_mode single
ENTSP_lu6 0 // We may be called from dual-issue code.
mkmsk r1, 1
stw r1, r0[0]
retsp 0
-
- Junior Member
- Posts: 4
- Joined: Sat Jan 07, 2017 10:39 pm
Got it, thanks! Specifically, I hadn't thought about the safe pointer adding boilerplate.