!
! The hand-generated code below should be producable by PSR's compiler if it:
! A) delays stores as late as possible
!
! B) remembers registers over procedure calls
!
! C) has a general algorithm for drop-through conditionally executed
! instructions, i.e. if there are no instructions between a conditional
! branch and its destination which set the condition codes, and the
! sequence is less that a certain length, then all the instructions
! within the sequence can be made conditional.
!
! D) does as above, but also allows instructions within the sequence
! whose subsequent execution depends on the same condition, e.g.
!
! %if a=b %and c=d %then a=b
!
! CmpS R0,R1 NAIVE STYLE
! Bne elsepart
! Cmps R2,R3
! Bne elsepart
! Mov R0,R2
!
! CmpS R0,R1 RULE (C) ABOVE
! Bne elsepart
! CmpS R2,R3
! MovEQ R0,R2
!
! CmpS R0,R1 RULE (D) SPECIAL CASE
! CmpSEQ R2,R3
! MovEQ R0,R2
!
! E) alters conditions to generate similar condition codes on
! condition AND condition AND condition to generate more cases
! to which rule (D) can be applied.
!
! F) adjusts constants in < or <= cases to favour above, i.e. turning
! CMP R,#const & BLE ... into CMP R,#const-1 & BLT ... etc.
!
! G) changes Newline back from the current implicit printsymbol(10) -
! there is no run-time overhead in moving the MOV R0,#10 over to
! the procedure body instead of having it in every call where it
! takes up space - after all, Peter's code-moving stuff ought to
! get %permroutine newline;printsymbol(10);%end correct - it will
! place the Mov R0,#10 before the body of %permroutine printsymbol
! and generate a suitable entry point for it...
! Personally, I would recommend stacking/restoring R0 as well
! as it might keep another variable in a register for a bit longer...
!
! I've only suggested optimisations which fit into the style of PSR's
! compilers...
!
%begin
%integer a,i,b
read(a)
! BL read_fn
! Str R0,a
read(i)
! BL read_fn
! Str R0,i
read(b)
! BL read_fn
%if a <= i <= b %start
! Ldr R1,a
! Ldr R2,i
! CmpS R1,R2
! CmpSLE R2,R0
i = 22
! MovLE R2,#22
%finish
%if 22 <= i <= b %start
! CmpS R2,#22-1
! CmpSGT R2,R0
i = 44
! MovGT R2,#44
%finish
%if a <= i <= 77 %start
! CmpS R1,R2
! CmpSLE R2,#77
i = 99
! MovLE R2,#99
%finish
%if 11 <= i <= 100 %start ;! Peter's special case when both const is good
! Sub R2,#11 ;! but usually corrupts a register needed later
! CmpS R2,#100-11
i = 1
! MovLS R2,#1
%finish
! Str R0,b
write(a,0)
! Mov R0,R1
! Mov R1,#0
! Bl Write
newline
! Bl Newline
! Mov R0,R2
write(i,0)
! Bl write
newline
! Bl newline
write(b,0)
! Ldr R0,b
! Bl write
newline
! Bl newline
%endofprogram