Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unnecessary instructions in LOOP forms #8

Open
takagi opened this issue Feb 28, 2015 · 1 comment
Open

Unnecessary instructions in LOOP forms #8

takagi opened this issue Feb 28, 2015 · 1 comment

Comments

@takagi
Copy link
Owner

takagi commented Feb 28, 2015

Situation
The language's loop form, currently implemented as a PIC macro, is compiled into instructions including SUBWF, BTFSC and a recursive function call.

For example, the following expression:

(loop 10
  0)        ; nop

is expanded into:

(let ((_loop (i)
        (if (= i 0)
          0
          (progn
            0
            (_loop (- i 1))))))
  (_loop 10)

then, is compiled into:

        MOVLW    00Ah
        MOVLW    I0
        GOTO     __LOOP1014
__LOOP1014
        MOVF     I0,W
        MOVWF    L0
        MOVLW   000h
        SUBWF   L0,W
        BTFSC   STATUS,Z
        GOTO    _ELSE10
        RETLW   000h
_ELSE10
        MOVLW   001h
        SUBWF   L0,W
        MOVWF   L1
        MOVF    L1,W
        MOVWF   I0
        GOTO    __LOOP1014

Problem
There are unnecessary instructions in the compiled assembly compared with the case using DECFSZ instruction.

  • get from and put into an input pseudo-register
  • the first GOTO instruction
  • a conditional branch with SUBWF and BTFSC instructions
  • SUBWF instruction for decrement

Goal
Make loop forms compiled into instructions using DECFSZ instruction.

        MOVLW    00Ah
        MOVWF    L0
__LOOP
        DECFSZ   L0,F
        GOTO     __LOOP
        RETLW    000h

Approach
The following approaches are considerable:

  • introducing loop syntax, not as a PIC macro
  • identifying loop structure to be optimized (chains of recurrences?)

Notes
There are some notes.

  • updating mdelay1 function's magic number
@takagi
Copy link
Owner Author

takagi commented Mar 3, 2015

For now, LOOP syntax is introduced in 1d6f5a9.

LOOP syntax

LOOP times body

Repeatedly executes body form for times times.

LOOP instruction

LOOP var body

Repeatedly executes body form for var times.

Register assignment

When a let bound variable is used as a function call's parameter in a LOOP syntax, it is assigned to a local pseudo-register, not to an input pseudo-register.

For example:

(let ((x (foo)))
  (loop 10
    (bar x)))

the let bound variable x is assigned to L0, not to I0.

Alive register

A register used as a loop counter in LOOP syntax keeps alive in the LOOP's body part.

For example,

(let ((x 10))
  (loop x
    (do-something)))

the local pseudo-register L0, assigned for x as a loop counter, keep alive in the loop and can not be assigned again.

NULL destination

For LOOP bodies, newly provided is NULL destination (:non-tail :null) which does not move and discards results of LOOP bodies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant