[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