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

Reply via email to