Hi, On Wed, Nov 6, 2024 at 7:13 AM Tomek CEDRO <to...@cedro.info> wrote:
> > Nathan you mentioned the 8-bit and 16-bit platforms to use 32-bit > unsigned. That would imply "virtual" type not natively supported by > platform. Do you know what is the penalty for using such types? Is it > safe? Does it work on all compilers? Is it slow? if no, then maybe we > could also use int64_t on 32-bit platforms? :-P > It's safe, widely supported by compilers, and "slow" in that multiple instructions will be used to support the operation instead of just one, and multiple registers will carry the value instead of just one. There's a penalty for it, but it's not really straightforward. Considering a Cortex-M0 based processor, arithmetic operations on 64-bit values will usually just be two or three instructions instead of one (eg, UMULL+MLA for a 64-bit multiply for one operand 32-bit or less, or UMULL+MLA+MLA for two 64-bit operands). The real penalty kicks in for function arguments, though. The common ARM calling convention reserves only four 32-bit registers for function arguments, so passing three 32-bit arguments is entirely in registers but passing three 64-bit arguments will put two 32-bit words on the stack. Similarly, only registers r0-r3 and r12 can be used freely while r4-r11 must have their values preserved. A function doing almost anything with a 64-bit value is likely to use more than five registers and will need to push and pop values. You can see the difference in compiled output for a 32-bit function doing a * b + c and a 64-bit function doing the same here: https://godbolt.org/z/8bKj6an4z As it happens the ARMv7 instruction set is designed to handle 64-bit values with a minimum of fuss. For giggles try changing the compiler used by godbolt to AVR GCC, where 64-bit multiplication is implemented as a libcall and the ABI requires that 18 or so registers get preserved by the callee if their contents can't be guaranteed to be non-volatile. I don't think, personally, that any of this is reason enough to worry about it. Using an int64_t for time_t is IMO a perfectly reasonable default for 32-bit and up targets. and possibly for all targets. Offering a kconfig option to support 32-bit (signed or unsigned) time_t offers an easy work-around should anyone find that the couple of percent increase in code size and execution time causes their project to fail - or if anyone is in the unfortunate situation where they depend on code that's made assumptions about size or signedness. -- Byron