Kingcom / armips

An assembler for various ARM and MIPS platforms. Builds available at http://buildbot.orphis.net/armips/
MIT License
363 stars 77 forks source link

Recursive macro calls in .if .elseif inside macro lead to max recursion #110

Closed Prof9 closed 7 years ago

Prof9 commented 7 years ago
// cached repeat
.macro .crepeat,index,count
    .if count < 0
        // count initialized once
        .crepeat index,3
    .elseif index < count
        .notice "test "+index
        .crepeat (index+1),count
    .endif
.endmacro
.crepeat 0,-1

This macro call should print three test lines; on the first call count < 0, so it's called again with count initialized to 3 (this would be replaced by an 'expensive' operation such as readu32()); then, it's called three times with index incrementing up to 3. However, the macro goes into max recursion instead and produces the following output:

test.asm(8) error: Parse error '.endif'
test.asm(2) error: Directive not terminated
test.asm(10) error: Max include/recursion depth reached
Kingcom commented 7 years ago

This is actually caused by numbers being stored and interpreted as unsigned in expressions, so count < 0 never returns true. Stems back from the time where all the expression evaluation was still using 32 bit types, which would lead to very... unintuitive results with addresses where bit 31 is set (like for PSX). As everything is using 64 bit math by now, it might be time to change them to be signed.

Prof9 commented 7 years ago

Seems to be fixed in 89ac362.