[fpc-devel] Is there a way to make Register Allocation inside of Interrupt Service Routines more efficient when using inline-assembler?
Michael Ring
mail at michael-ring.org
Sun Aug 21 13:32:12 CEST 2016
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 at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
More information about the fpc-devel
mailing list