[Bug c++/79241] error wen compiling -Os, OK with another optimizations

2018-11-20 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79241

--- Comment #9 from night_ghost at ykoctpa dot ru ---
Seems that I missed a bugfix patch. Where I can download fixed GCC 5.4 to test?

[Bug target/70676] suboptimal code generation on AVR

2017-07-03 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70676

night_ghost at ykoctpa dot ru changed:

   What|Removed |Added

 Status|RESOLVED|REOPENED
 Resolution|INVALID |---

--- Comment #9 from night_ghost at ykoctpa dot ru ---
Really this is a best way to fix bugs! Just ignore them - like an ostrich,
hiding  head in the sand.

[Bug c++/79241] error wen compiling -Os, OK with another optimizations

2017-02-20 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79241

--- Comment #7 from night_ghost at ykoctpa dot ru ---
Created attachment 40779
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40779=edit
testcase

ii and console log. If I change from -Os to any other mode then it compiles OK

[Bug c++/79241] error wen compiling -Os, OK with another optimizations

2017-01-26 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79241

--- Comment #5 from night_ghost at ykoctpa dot ru ---
I'll try to exclude maximum of unneeded code from testcase and then upload it.

[Bug c++/79241] error wen compiling -Os, OK with another optimizations

2017-01-26 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79241

--- Comment #2 from night_ghost at ykoctpa dot ru ---
90mbytes of code? you must be joking! But when I try to do a testcase with only
few files then all compiles OK. Moreover the classes which uses
FUNCTOR_BIND_MEMBER  without additional "using namespace " all compiles
fine too.

[Bug c++/79241] New: error wen compiling -Os, OK with another optimizations

2017-01-26 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79241

Bug ID: 79241
   Summary: error wen compiling -Os, OK with another optimizations
   Product: gcc
   Version: 4.8.3
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: night_ghost at ykoctpa dot ru
  Target Milestone: ---

When I compile this (https://github.com/night-ghost/ardupilot) project with -Os
I got errors

==
In file included from
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL/AP_HAL_Namespace.h:4:0,
 from
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL/AP_HAL.h:6,
 from
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL_REVOMINI/AnalogIn.cpp:22:
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL/utility/functor.h:
In instantiation of 'static constexpr Functor<RetType, Args> Functor<RetType,
Args>::bind(T*) [with T = REVOMINI::REVOMINIAnalogIn; RetType (T::*
method)(Args ...) = ::REVOMINIAnalogIn::_timer_event; RetType = void;
Args = {}]':
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL_REVOMINI/AnalogIn.cpp:48:43:
  required from here
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL/utility/functor.h:73:49:
error: could not convert '{obj, method_wrapper<REVOMINI::REVOMINIAnalogIn,
::REVOMINIAnalogIn::_timer_event>}' from '' to 'Functor'
 return { obj, method_wrapper<T, method> };
 ^
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL/utility/functor.h:74:5:
error: body of constexpr function 'static constexpr Functor<RetType, Args>
Functor<RetType, Args>::bind(T*) [with T = REVOMINI::REVOMINIAnalogIn; RetType
(T::* method)(Args ...) = ::REVOMINIAnalogIn::_timer_event; RetType =
void; Args = {}]' not a return-statement
 }
 ^
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL/utility/functor.h:
In static member function 'static constexpr Functor<RetType, Args>
Functor<RetType, Args>::bind(T*) [with T = REVOMINI::REVOMINIAnalogIn; RetType
(T::* method)(Args ...) = ::REVOMINIAnalogIn::_timer_event; RetType =
void; Args = {}]':
/mnt/disk_d/src/quad-copter/ardu-copter/3.4.2-git/ardupilot.3.4-revo/libraries/AP_HAL/utility/functor.h:74:5:
warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
make: *** [/tmp/ArduCopter.build/libraries/AP_HAL_REVOMINI/AnalogIn.o] Ошибка 1
==

but all OK with -O0, -Og and -O2

moreover all turns to OK when I change

#include "functor.h"

to 

#pragma GCC push_options
#pragma GCC optimize ("O2")
#include "functor.h"
#pragma GCC pop_options

(https://github.com/night-ghost/ardupilot/blob/RevoMini/libraries/AP_HAL/utility/functor.h)

tested on GCC 4.8.3, 4.9 and 5.4 with same results

[Bug target/70676] suboptimal code generation on AVR

2016-12-05 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70676

--- Comment #6 from night_ghost at ykoctpa dot ru ---
I reported not one case but suboptimal behavior while optimizing size - GCC
optimization of sibling calls increases size of binary. There are a lot of such
places in this code.

And GCC never replaces call-ret sequence to jmp, relying on linkers optimizing
by -relax. But including -relax flag often spoils the project to complete
failure.

[Bug target/70677] Suboptimal cond on AVR: unneeded stack frame

2016-05-25 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70677

--- Comment #6 from night_ghost at ykoctpa dot ru ---
Thank you again for such good key - it saves me 150 bytes. Moreover this key is
not listed in GCC's possible optimisations for AVR. 


PS. Why it not included by default to -Os? What can be affected by it?

[Bug target/70676] suboptimal code generation on AVR

2016-05-24 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70676

--- Comment #4 from night_ghost at ykoctpa dot ru ---
Created attachment 38551
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38551=edit
testcase in attachment

without -no-optimize-sibling-call

reported bug can be found in MinimOsd_Extra.s on lines 2424, 3249 and so on -
all POP's of epilogue can be done before comparison.

If GCC can't move up epilogue to that place then such optimization is not
suitable for -Os because it means "in size at the expense of the rest", 
especially on embedded, where task - to shove an elephant into a beaker (I can
not better translate Russian proverb "Впихнуть невпихнуемое")

[Bug target/70677] Suboptimal cond on AVR: unneeded stack frame

2016-05-24 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70677

--- Comment #4 from night_ghost at ykoctpa dot ru ---
Created attachment 38550
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38550=edit
testcase in attachment

for AVR platform arduino.h is the most that neither is a standard :)

[Bug target/70677] Suboptimal cond on AVR: unneeded stack frame

2016-05-23 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70677

--- Comment #2 from night_ghost at ykoctpa dot ru ---
all code samples from
https://github.com/night-ghost/minimosd-extra/tree/master/MinimOsd_Extra. When
I try to isolate a piece of code with a bug in one file, it is compiled
differently than in their native place.

Same stack usage in this code:

#include 

#define SCK_PIN   13
#define MISO_PIN  12
#define MOSI_PIN  11

class SPI
{
  public:
SPI(void);
 static byte transfer(byte);
};

SPI::SPI()
{
  // initialize the SPI pins
  pinMode(SCK_PIN, OUTPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);
}

byte SPI::transfer(byte value){
  SPDR = value;
  while (!(SPSR & (1<<SPIF))) ;
  return SPDR;
}

void MAX_write(byte addr, byte data){
register byte d=data;
SPI::transfer(addr);
SPI::transfer(d);
}

will be 

void MAX_write(byte addr, byte data){
 f06:<->cf 93   <-->push<-->r28
 f08:<->df 93   <-->push<-->r29
 f0a:<->1f 92   <-->push<-->r1
 f0c:<->cd b7   <-->in<>r28, 0x3d<->; 61
 f0e:<->de b7   <-->in<>r29, 0x3e<->; 62
register byte d=data;
SPI::transfer(addr);
 f10:<->69 83   <-->std<--->Y+1, r22<-->; 0x01
 f12:<->0e 94 e2 2e <-->call<-->0x5dc4<>; 0x5dc4 <_ZN3SPI8transferEh>
SPI::transfer(d);
 f16:<->69 81   <-->ldd<--->r22, Y+1<-->; 0x01
 f18:<->86 2f   <-->mov<--->r24, r22
 f1a:<->0e 94 e2 2e <-->call<-->0x5dc4<>; 0x5dc4 <_ZN3SPI8transferEh>
}
 f1e:<->0f 90   <-->pop<--->r0
 f20:<->df 91   <-->pop<--->r29
 f22:<->cf 91   <-->pop<--->r28
 f24:<->08 95   <-->ret

as one can see, "data" variable saved in stack, not in register

[Bug target/70676] suboptimal code generation on AVR

2016-05-23 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70676

--- Comment #2 from night_ghost at ykoctpa dot ru ---
*** testcase for call+ret: (all code from
https://github.com/night-ghost/minimosd-extra/tree/master/MinimOsd_Extra),
compile with  -fno-optimize-sibling-calls

#include 

class SPI
{
  public:
SPI(void);
static byte transfer(byte);
};

SPI::SPI()
{
#define SCK_PIN   13
#define MISO_PIN  12
#define MOSI_PIN  11

  // initialize the SPI pins
  pinMode(SCK_PIN, OUTPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);
}

byte SPI::transfer(byte value){
  SPDR = value;
  while (!(SPSR & (1<<SPIF))) ;
  return SPDR;
}


byte MAX_read(byte addr){
  SPI::transfer(addr);
  return SPI::transfer(0xff);
}



*** testcase of splitting tail, compile without  -fno-optimize-sibling-calls

#include 
#define NOINLINE __attribute__ ((noinline))

struct Point {
byte x;
byte y;
};

typedef struct Point point;

static boolean inline is_alt(point p){
return (p.y & 0x40);
}

static void NOINLINE osd_printf_1(PGM_P fmt, float f){
Serial.printf_P(fmt, f);
}

static void NOINLINE osd_printf_2(PGM_P fmt, float f, byte c){
Serial.printf_P(fmt, f);
Serial.write(c);
}

static void panBatteryPercent(point p){

float val=2.0;


   if (is_alt(p))
   osd_printf_1(PSTR("%2.0f%%"),val);
else
   osd_printf_2(PSTR("%4.0f\x01"),val,0x15);
}

}

>Provided you use -mrelax (or link with -Wl,--relax), the linker tries to 
>replace [R]CALL+RET by [R]JMP instruction

Thanks for good key, it saves  700bytes of code (from 30642 to 29942)

[Bug target/70677] New: Suboptimal cond on AVR: unneeded stack frame

2016-04-15 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70677

Bug ID: 70677
   Summary: Suboptimal cond on AVR: unneeded stack frame
   Product: gcc
   Version: 5.3.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: night_ghost at ykoctpa dot ru
  Target Milestone: ---

here a lot of commands to deal with stack frame for only one byte

//(out of scope:
struct Point {
byte x;
byte y;
};

static boolean inline is_alt(point p){
return (p.y & 0x40);
}
//)

static void panVel(point p){
1e14:   cf 93   pushr28
1e16:   df 93   pushr29
1e18:   1f 92   pushr1
1e1a:   cd b7   in  r28, 0x3d   ; 61
1e1c:   de b7   in  r29, 0x3e   ; 62

printSpeed(cnvGroundSpeed(),is_alt(p));
1e1e:   96 fb   bst r25, 6
1e20:   22 27   eor r18, r18
1e22:   20 f9   bld r18, 0
1e24:   29 83   std Y+1, r18; 0x01
1e26:   0e 94 33 09 call0x1266; 0x1266 <_ZL14cnvGroundSpeedv>
1e2a:   ab 01   movwr20, r22
1e2c:   bc 01   movwr22, r24
}

1e2e:   29 81   ldd r18, Y+1; 0x01
1e30:   87 e8   ldi r24, 0x87   ; 135
1e32:   92 e0   ldi r25, 0x02   ; 2
1e34:   0e 94 c6 0e call0x1d8c; 0x1d8c <_ZL10printSpeedPKcfh>

1e38:   0f 90   pop r0
1e3a:   df 91   pop r29
1e3c:   cf 91   pop r28
1e3e:   08 95   ret

R18 can be PUSH'ed, moved to r28 or even calculated after call to x1266

[Bug target/70676] New: suboptimal code generation on AVR

2016-04-15 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70676

Bug ID: 70676
   Summary: suboptimal code generation on AVR
   Product: gcc
   Version: 5.3.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: night_ghost at ykoctpa dot ru
  Target Milestone: ---

gcc -Os -fno-optimize-sibling-calls

don't optimizes out tail recursion:

return SPI::transfer(0xff);
 f54:8f ef   ldi r24, 0xFF; 255
 f56:0e 94 d9 2e call 0x5db2 ; 0x5db2 <_ZN3SPI8transferEh>
}
 f5a:08 95   ret

where it should be 
 ldi r24, 0xFF; 255
 jmp  0x5db2 ; 0x5db2 <_ZN3SPI8transferEh>

Yes I can remove -fno-optimize-sibling-calls but then size of compiled project
will be much more:

with:30566 bytes (93.3% Full)
without: 30772 bytes and binary don't fit to flash (30720 is maximum)

Reason is that even with -Os optimize-sibling-calls tries to make epilogue for
each tail recursion:


2080:<->92 e0   <-->ldi<--->r25, 0x02<->; 2
2082:<->df 91   <-->pop<--->r29
2084:<->cf 91   <-->pop<--->r28
2086:<->1f 91   <-->pop<--->r17
2088:<->0f 91   <-->pop<--->r16
208a:<->ff 90   <-->pop<--->r15
208c:<->ef 90   <-->pop<--->r14
208e:<->bf 90   <-->pop<--->r11
2090:<->af 90   <-->pop<--->r10
2092:<->9f 90   <-->pop<--->r9
2094:<->8f 90   <-->pop<--->r8
2096:<->0c 94 2a 0f <-->jmp<--->0x1e54<>; 0x1e54
<_ZL12osd_printf_1PKcf>
(rjmp here)
209a:<->df 91   <-->pop<--->r29
209c:<->cf 91   <-->pop<--->r28
209e:<->1f 91   <-->pop<--->r17
20a0:<->0f 91   <-->pop<--->r16
20a2:<->ff 90   <-->pop<--->r15
20a4:<->ef 90   <-->pop<--->r14
20a6:<->bf 90   <-->pop<--->r11
20a8:<->af 90   <-->pop<--->r10
20aa:<->9f 90   <-->pop<--->r9
20ac:<->8f 90   <-->pop<--->r8
20ae:<->08 95   <-->ret

Can GCC in -Os really optimize only size and rollback optimizations if size of
"optimized" code is more than size of non-optimized ?

[Bug target/69049] [avr] strange/unnecessary commands in compiled code

2016-01-29 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69049

--- Comment #2 from night_ghost at ykoctpa dot ru ---
1) this is part of Arduino project so it should #include Arduino.h
2) GCC 5.3 don't has this bug so it can be closed

[Bug lto/69408] LD crashes with LTO

2016-01-27 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69408

--- Comment #14 from night_ghost at ykoctpa dot ru ---
Created attachment 37487
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37487=edit
script to build GCC-avr and other tools

use this script to build GCC

[Bug lto/69408] LD crashes with LTO

2016-01-27 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69408

--- Comment #15 from night_ghost at ykoctpa dot ru ---

steps to repeat:

Arduino recent version should be installed

GCC created by the above script should be in PATH and in Arduino's
/usr/share/arduino/hardware/tools/avr


un-tar testcase, cd to it.

in mk/board_avr.mk one should set path to liblto_plugin.so

then

cd ArduCopter
make

after lots of compilation you'll get

%% ArduCopter.elf
collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core
dumped
compilation terminated.
make: *** [/tmp/ArduCopter.build/ArduCopter.elf] Ошибка 1
make: *** Удаляется файл `/tmp/ArduCopter.build/ArduCopter.elf'


PS. I can't upload testcase because of size limit 1mb. Is there another way to
send it?

[Bug lto/69408] LD crashes with LTO

2016-01-25 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69408

--- Comment #4 from night_ghost at ykoctpa dot ru ---
I can attach script which GCC has been built, and ZIP of the project tree which
cause crash.

[Bug lto/69408] New: LD crashes with LTO

2016-01-21 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69408

Bug ID: 69408
   Summary: LD crashes with LTO
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: critical
  Priority: P3
 Component: lto
  Assignee: unassigned at gcc dot gnu.org
  Reporter: night_ghost at ykoctpa dot ru
  Target Milestone: ---

trying to compile Arducopter 3.2.1 for AVR I got crash:

%% ArduCopter.cpp
%% ArduCopter.elf
collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core
dumped
compilation terminated.
make: *** [/tmp/ArduCopter.build/ArduCopter.elf] Ошибка 1
make: *** Удаляется файл `/tmp/ArduCopter.build/ArduCopter.elf'

but there is no .core file in popular places.

without LTO build successed

[Bug lto/69408] LD crashes with LTO

2016-01-21 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69408

--- Comment #2 from night_ghost at ykoctpa dot ru ---
there are reqirements for reporting *language* bugs but no LTO bugs in
https://gcc.gnu.org/bugs.html

I can ZIP build tree but I saw a list of all that i can send in the "we do not
want". Crash occurs on final linking so I can't give the refined test case. But
crash always comes.

[Bug c/69049] New: [avr] strange/unnecessary commands in compiled code

2015-12-24 Thread night_ghost at ykoctpa dot ru
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69049

Bug ID: 69049
   Summary: [avr] strange/unnecessary commands in compiled code
   Product: gcc
   Version: 4.9.2
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: night_ghost at ykoctpa dot ru
  Target Milestone: ---

small code

void deepSleep(uint16_t milliseconds) {
uint32_t microseconds = milliseconds * 1000L;
uint16_t sleep_periods = (microseconds - watchdogTime_us) /
watchdogTime_us;

while (sleep_periods >= 512) {
  narcoleptic_sleep_down(WDTO_8S);
  sleep_periods -= 512;
}
if (sleep_periods & 256) narcoleptic_sleep_down(WDTO_4S); /* xxx */
}

compiled as (see comments)

void deepSleep(uint16_t milliseconds) {

uint32_t microseconds = milliseconds * 1000L;
2fb2:   9c 01   movwr18, r24
2fb4:   a8 ee   ldi r26, 0xE8   ; 232
2fb6:   b3 e0   ldi r27, 0x03   ; 3
2fb8:   0e 94 b8 33 call0x6770  ; 0x6770 <__umulhisi3>

uint16_t sleep_periods = (microseconds - watchdogTime_us) /
watchdogTime_us;
2fbc:   6c 19   sub r22, r12
2fbe:   7d 09   sbc r23, r13
2fc0:   8e 09   sbc r24, r14
2fc2:   9f 09   sbc r25, r15
2fc4:   a7 01   movwr20, r14
2fc6:   96 01   movwr18, r12
2fc8:   0e 94 71 33 call0x66e2  ; 0x66e2 <__udivmodsi4>
2fcc:   69 01   movwr12, r18 // r12r13 === sleep_periods,
is'nt it?

while (sleep_periods >= 512) {
//{ why GCC adds 0 before comparison?
2fce:   e1 2c   mov r14, r1
2fd0:   f1 2c   mov r15, r1
2fd2:   c7 01   movwr24, r14
2fd4:   8c 0d   add r24, r12
2fd6:   9d 1d   adc r25, r13
// carry NEVER can be set - r1===0
2fd8:   81 15   cp  r24, r1
//}
2fda:   92 40   sbcir25, 0x02   ; 2
2fdc:   70 f0   brcs.+28; 0x2ffa
<_Z9deepSleepj+0x6c>
  narcoleptic_sleep_down(WDTO_8S);
2fde:   89 e0   ldi r24, 0x09   ; 9
//{ why GCC saves unneeded LONG?
2fe0:   29 83   std Y+1, r18; 0x01
2fe2:   3a 83   std Y+2, r19; 0x02
2fe4:   4b 83   std Y+3, r20; 0x03
2fe6:   5c 83   std Y+4, r21; 0x04
//}
2fe8:   0e 94 c4 17 call0x2f88  ; 0x2f88
<_Z22narcoleptic_sleep_downh>
2fec:   62 e0   ldi r22, 0x02   ; 2
2fee:   f6 1a   sub r15, r22
//{ why GCC restores unneeded LONG?
2ff0:   5c 81   ldd r21, Y+4; 0x04
2ff2:   4b 81   ldd r20, Y+3; 0x03
2ff4:   3a 81   ldd r19, Y+2; 0x02
2ff6:   29 81   ldd r18, Y+1; 0x01
//}
2ff8:   ec cf   rjmp.-40; 0x2fd2
<_Z9deepSleepj+0x44>

//{ what the hell here? where such calculations in C code?
2ffa:   f9 01   movwr30, r18
2ffc:   ef 2f   mov r30, r31
2ffe:   ff 27   eor r31, r31
3000:   e6 95   lsr r30
3002:   60 e0   ldi r22, 0x00   ; 0
3004:   7e ef   ldi r23, 0xFE   ; 254
3006:   e6 9f   mul r30, r22
3008:   c0 01   movwr24, r0
300a:   e7 9f   mul r30, r23
300c:   90 0d   add r25, r0
300e:   f6 9f   mul r31, r22
3010:   90 0d   add r25, r0
3012:   11 24   eor r1, r1
3014:   82 0f   add r24, r18
3016:   93 1f   adc r25, r19
//}
  sleep_periods -= 512;
}

if (sleep_periods & 256) narcoleptic_sleep_down(WDTO_4S);
3018:   90 ff   sbrsr25, 0
301a:   0d c0   rjmp.+26; 0x3036
<_Z9deepSleepj+0xa8>
301c:   88 e0   ldi r24, 0x08   ; 8
}
//{ optimization on size but GCC generates 2nd epilogue to escape tail
recursion while simple CALL takes less memory
301e:   0f 90   pop r0
3020:   0f 90   pop r0
3022:   0f 90   pop r0
3024:   0f 90   pop r0
3026:   df 91   pop r29
3028:   cf 91   pop r28
302a:   ff 90   pop r15
302c:   ef 90   pop r14
302e:   df 90   pop r13
3030:   cf 90   pop r12
while (sleep_periods >= 512) {
  narcoleptic_sleep_down(WDTO_8S);
  sle