Skip to content

[AVR] fix OpCp2Op optimization

ccrause requested to merge ccrause/fpc-source:OpCp2Op into main

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

Merge request reports