Was getting high hopes for a moment...
@Charlie: the last point you mention, this optimization is already
there. As long as I do not call a procedure and directly include inline
assembler in the interrupt routine all is fine, only really used
registers are in the list of registers that need to get saved and the
interrupt handlers gets quite lean & efficient.
@Sergej: I just started wondering on usage of fp registers, when I call
a routine that uses floating point I see that the fp registers are not
marked as reserved by the compiler, what do you think?
The procedure below (test) uses $f0 and $f2 but they are not marked as
allocated:
# Register
at,v0,v1,a0,a1,a2,a3,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ra allocated
jal P$TEST_$$_TEST
nop
# Register
at,v0,v1,a0,a1,a2,a3,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ra released
could this be a bug? (I have also modified
tcpuparamanager.get_volatile_registers_fp to return [] so i'd expect to
see $f0..$f19 pushed to stack but I see nothing)
Could of course be me causing this bug, but I checked my diff to trunk,
I have not knowingly changed fp behaviour besides changing
get_volatile_registers_fp
Michael
procedure test;
var
b : real;
begin
b := sqrt(a);
end;
procedure test_interrupt; interrupt;
var
b : real;
begin
inc(a);
asm
nop
end ['a0'];
test;
//b := round(a);
end;
Michael
Am 21.08.16 um 12:25 schrieb Karoly Balogh (Charlie/SGR):
Hi,
On Sun, 21 Aug 2016, Sergei Gorelkin wrote:
It is actually the opposite way around.
g_save_registers/g_restore_registers methods are only used for first
implemented targets (i386 and maybe m68k). All newer targets are written
without calling them, since they are completely inappropriate to
implement stack frame optimizations or push/pop-alike instructions for
register saving.
Well, they still have stubs in the HLCG, which is why I thought it must be
newer than just dumping everything in g_proc_entry. Actually, I
implemented them quite recently for 68k, and they're still routed in live
code in psub.pas.
However, since historically I missed the large compiler refactor in the
mid-'00s, I believe you. Anyway...
MIPS codegenerator does check which registers are actually used. The
issue is, a procedure with 'interrupt' modifier must not modify any
registers at all because it can be called asynchronously. As soon as an
'interrupt' procedure calls another (regular) procedure, the callee may
modify any registers from volatile list, and the caller has no way to
know which ones. Therefore, it has no other option than to save/restore
all volatile registers.
Well, one possible optimization would be to only save all volatiles if the
interrupt routine actually calls another function. Otherwise only save the
ones used by the current proc. This would allow some very small and very
fast interrupt functions, right? I'm not sure though if there's an easy
way to determine if there is a function call inside the function I'm
generating code for.
Maybe at the point of generating a function call, if the current proc is
an interrupt, mark all volatiles as used somehow?
Charlie
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel