[AVR] fix OpCp2Op optimization
Summary
Currently the OpCp2Op optimization generates incorrect instructions for certain expressions containing the and operator.
System
- Operating system: Embedded
- Processor architecture: AVR
- Device: Microcontroller
What is the current bug behavior?
Consider the following test code:
program testsimavr;
var
b: byte = $05;
begin
writeln('if ($05 and $03) = $03 then');
if (b and $03) = $03 then
writeln('Wrong')
else
writeln('OK');
writeln('if ($05 and $03) = $00 then');
if (b and $03) = $00 then
writeln('Wrong')
else
writeln('OK');
end.
When compiled with -O2 or higher, the expression if (b and $03) = $03 then
is converted to the following incorrect instructions:
# [8] if (b and $03) = $03 then
lds r18,(TC_sPsTESTSIMAVR_ss_B)
andi r18,3
breq .Lj4
.Ll4:
What is the behavior after applying this patch?
The optimization OpCp2Op is only performed when the first operation is andi and the comparison is against 0.
Relevant logs and/or screenshots
Current behaviour:
$ ~/fpc/installs/lib/fpc/3.3.1/ppcrossavr -O2 -Wpavrsim testsimavr.pp
$ ~/LazProjs/fp-avrsim-cc/avrsim testsimavr.bin
if ($05 and $03) = $03 then
Wrong
if ($05 and $03) = $00 then
OK
After this modification:
$ ~/fpc/gitlab-cc/compiler/avr/pp -n @~/fpc/gitlab-cc/fpc.cfg -O2 -Wpavrsim testsimavr.pp
Free Pascal Compiler version 3.3.1 [2023/03/08] for avr
Copyright (c) 1993-2023 by Florian Klaempfl and others
Target OS: Embedded
Compiling testsimavr.pp
Assembling testsimavr
Linking testsimavr
19 lines compiled, 0.1 sec, 4070 bytes code, 8607 bytes data
$ ~/LazProjs/fp-avrsim-cc/avrsim testsimavr.bin
if ($05 and $03) = $03 then
OK
if ($05 and $03) = $00 then
OK