kevinpt / opbasm

Open PicoBlaze Assembler
http://kevinpt.github.io/opbasm/
MIT License
60 stars 13 forks source link

Nested for loops run infinitely #5

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
* What steps will reproduce the problem?

NAMEREG s1, LOOP_R
NAMEREG s2, IN_LOOP_R
  LOAD s3, 32
  for( LOOP_R := 0, LOOP_R != s3, LOOP_R := LOOP_R + 1 ) {
    for( IN_LOOP_R := 0, IN_LOOP_R != 1, IN_LOOP_R := IN_LOOP_R + 1, `
      OUTPUT   IN_LOOP_R, 01
    ')
  }

* What is the expected output? What do you see instead?
Expected generated output:

; Expression: LOOP_R := 0
load LOOP_R, 00

FOR_f1_0038:
; If LOOP_R != s3
compare LOOP_R, s3
jump z, EQ_f1_0041

; Expression: IN_LOOP_R := 0
load IN_LOOP_R, 00

FOR_f1_0043:
; If IN_LOOP_R != 1
compare IN_LOOP_R, 01
jump z, EQ_f1_0046

  OUTPUT   IN_LOOP_R, 01

NEXTFOR_f1_0044:                                        
; Expression: IN_LOOP_R := IN_LOOP_R + 1

add IN_LOOP_R, 01

jump FOR_f1_0043                                        

EQ_f1_0046:

ENDLOOP_f1_0045:

NEXTFOR_f1_0039: 
; Expression: LOOP_R := LOOP_R + 1 

add LOOP_R, 01

jump FOR_f1_0038    *******************

EQ_f1_0041:

ENDLOOP_f1_0040:

Instead of "jump FOR_f1_0038" we get "jump FOR_f1_0043" pointing back to the 
start of the inner loop and resulting in an infinite loop.

* What version of the product are you using? On what operating system?

opbasm 1.2 on Linux CentOS 6.6
2.6.32-504.16.2.el6.x86_64 #1 SMP Wed Apr 22 06:48:29 UTC 2015 x86_64 x86_64 
x86_64 GNU/Linux

* Please provide any additional information below.

This can be worked around by defining an extra "for_inner()" M4 macro that is 
identical to the existing M4 "for()" macro in "picoblaze.m4" but replacing the 
label names.  Note: `popdef(_slbl)' appears to be missing at the end of the for 
macro.

Original issue reported on code.google.com by robbinss...@gmail.com on 24 Apr 2015 at 12:09

GoogleCodeExporter commented 9 years ago
Good catch. I can't test this in simulation until this evening but the missing 
popdef(_slbl) is the cause. m4 maintains a stack of variable definitions which 
is how the nesting works for if() and all the other control flow macros like 
for(). The missing pop causes a jump back into the inner loop because _slbl 
hasn't been restored to its previous value. You shouldn't need an additional 
macro like for_inner() since that would not work for more than two levels of 
nesting.

If you want to apply the fix now just change the last line of the macro to this:

_elbl:' `popdef(`_slbl')'`popdef(`_clbl')'`popdef(`_elbl')')

You'll either have to reinstall Opbasm with the modified picoblaze.m4 or 
manually run it with "python path/to/opbasm.py <your command line options>".

Original comment by kevin.thibedeau on 24 Apr 2015 at 2:23

GoogleCodeExporter commented 9 years ago
Yes, I can confirm that this fix works.  I managed to not reference the correct 
picoblaze.m4 file the first time I tested it here, but it works now.  Thanks!

Original comment by robbinss...@gmail.com on 24 Apr 2015 at 3:39

GoogleCodeExporter commented 9 years ago
Bug in macro has been fixed

Original comment by kevin.thibedeau on 7 May 2015 at 5:59