kevinpt / opbasm

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

Expression evaluation is limited to a single constant #8

Closed tpambor closed 9 years ago

tpambor commented 9 years ago

First of all I am relatively new to opbasm but I really like the already huge feature set.

As to my problem I have tried using multiple constants in an eval expression with the simple testcase below but unfortunately I stumbled across some problems.

constant foo, 55
constant bar, AA

load s0, evalh(foo)
load s1, evalh(bar)
load s2, evalh(0x55 | 0xAA)
load s3, evalh(foo | bar)
load s4, evalh(evalc(foo) | evalc(bar))

The code generated by m4 is:

constant foo, 55 
constant bar, AA 

load s0, 55  ; foo
load s1, aa  ; bar
load s2, ff  ; 0x55 | 0xAA
load s3,   ; foo | bar
load s4, ff  ; 85 | 170

with telling me:

m4:stdin:7: bad expression in eval (bad input): (foo | bar) & 0xFF
m4:stdin:8: empty string treated as 0 in builtin `eval'
m4:stdin:8: empty string treated as 0 in builtin `eval'

My expectation was that load s3, evalh(evalc(foo) | evalc(bar)) would be evaluated to load s3, ff. I tried to workaround by using load s4, evalh(evalc(foo) | evalc(bar)) which actually resulted in the correct output but creates two warnings. Are there any negative side effects on using this workaround beside the warnings? Is there another macro that I should prefer?

Nevertheless supporting the syntax in line 7 would greatly increase readability of the code.

kevinpt commented 9 years ago

The eval[dhb]() macros are able to handle a single constant name as their argument and substitute its value but as you've found that doesn't work if the argument is an expression. The documentation should be clearer on this. Your workaround is fine. The warnings are from m4 complaining that the optional 2nd and 3rd arguments to evalc() are missing even though they are referenced in the expansion. You can use the const2m4() macro instead to get the same effect without any warnings. You can also just declare foo and bar as m4 macros and get a cleaner expression:

define(`foo', 0x55)
define(`bar', 0xAA)
load s5, evalh(foo | bar)

Expansion:

 load s5, ff                    ; 0x55 | 0xAA

When this is done, these constants are no longer visible to the assembler itself and won't be listed in the log. You have to remember to convert them back to PicoBlaze format with one of the eval*() helpers.