In most cases, calling & writing leaf functions involved no stack manipulation, which is a good thing IMO, leaving the load-store units dealing with global changes rather than confusing them with locals.
I would guess this is also a big deal squeezing code into a small amount of local memory too: you need less inlining, and have less bloat saving/restoring on function calls.
in the absence of hard data saying otherwise, it sounds better to go for a roughly 50:50 split between caller & callee saved.
non-leaf functions can still use the extra registers for intermediates between function calls.
larger leaf-functions can still the whole register range by actually saving.
I can also see a good case for reserving some for globals (localstore pointer, message queue ?).like 'thread-local storage' or values related to the current Task.
again MIPS had a 'global pointer' which was left pointing at global variables, allowing them to be accessed with compact addressing modes.
I gather the epiphany instruction set allows smaller instructions using the first 8 registers, what is their best use?
Should those also be split e.g. r0-r3=caller-saved, r4-r7=callee-saved, r8-r31=caller,r32-r55=callee ; r56-63=special purpose globals ?
maybe its' simpler to just keep 0-7 'scratch area'/return values & function arguments (2 return values, 6 args)
.. or is that getting too convoluted.
another way would be to use 'odd/even' registers as caller/calleeStatistics: Posted by dobkeratops — Tue Aug 04, 2015 3:43 pm
]]>