8*8 to 16 or 16*16 to 32 bit multiplication give incorrect result
Original Reporter info from Mantis: g.hieber
-
Reporter name: Georg Hieber
Original Reporter info from Mantis: g.hieber
- Reporter name: Georg Hieber
Description:
Var res: longword; f1, f2: word;
begin
res := f1 * f2;
end;
The above code snippet is completely legal, and the result of a multiplication of 2 16 bit factors into a 32 bit variable should be (and is on a "normal", 32 or 64 bit machine) correct.
the code generated by ppcrossavr does not give that result, the upper 16 bits are zeroed, and the compiler gives a warning like „Hint: Converting the operands to "LongWord" before doing the multiply could prevent overflow errors.“ 8 to 16, or 32 to 64 bit multiplications behave exactly the same. This seems to be intended, but I consider it wrong. I did not find any note in the docs describing this restriction.
In 32 or 64 bit systems this behavior is probably masked because every arithmetic is internally done 32 or 64 bit wide, and smaller operands are implicitly converted to this size.
btw., signed operands behave exyactly the same.
Steps to reproduce:
compile any source code containing 8bit8bit to 16bit, or 16bit16bit to 32bit, or 32bit * 32 bit to 64 bit multiplications with ppcrossavr end examine the generated assembler code.
Additional information:
of course, converting the 16bit operands into 32bit variables and then doing a 32bit multiplication, be it by explicit typecast or implicitly by the compiler, solves the problem. However, this is not a very desirable solution. A 32 bit multiplication takes 4 times as much time as a 16bit one (if you have 8bit multiply in the processor's instruction set), and a n*n bit multiplication routine nearly automatically yields a 2n bit result.
I am aware, that this will be not easy to implement, but it must have been considered before when the code generator was written. Procedure a_mul_reg_reg_pair has been defined, but apparently never been implemented for any target.
I suggest to fix the issue the easiest way quickly, but to keep the "good" solution in mind.
Mantis conversion info:
- Mantis ID: 27739
- OS: embedded
- Platform: avr
- Version: 3.1.1
- Fixed in version: 3.1.1
- Fixed in revision: 1154 (#77db0e51)
- Target version: 3.0.0