3

I have a macro which performs a comparison, and jumps to the end of the macro if that comparison isn't true. Here is a simplified example:

.macro do_work_if_value_not_zero value
    li s0, value
    bne s0, zero, exit_label
    nop   

    // Do work

    exit_label:
.endm

The issue however is that I call this macro several times like so:

do_work_if_value_not_zero 5
do_work_if_value_not_zero 3
do_work_if_value_not_zero 12

As a result I receive the following error:

Error: symbol `exit_label' is already defined



Because I never call the macro with the same parameter multiple times, I attempted to use the parameter name concatenated with a ':' to create a unique label like so:

.macro do_work_if_value_not_zero value
    li s0, value
    bne s0, zero, \value
    nop   

    // Do work

    \value:
.endm

However this did not seem to work, and I received more errors.

Thus my question is, how can one create a unique exit label for each macro call to avoid this issue?

  • what if you did `\value :` (note the whitespace). I don't have an environment set up to test this, but this link gave me the idea: https://sourceware.org/binutils/docs/as/Macro.html#Macro – Christian Gibbons Apr 23 '18 at 05:09
  • Thank you for the comment, unfortunately adding the whitespace resulted in the same problem: It works for one call to the macro, but not multiple =/ – user9683851 Apr 23 '18 at 05:14
  • Maybe it doesn't like you making a label out of it when you are also using it as a value. Try passing in a second parameter to your macro that will be used purely for the label. – Christian Gibbons Apr 23 '18 at 05:20
  • Ahh nice this works! I also realized why your other suggestion didn't work: since value is a number, we can't use it as a label name because its' value isn't a proper line number we can jump to (I think). The solution was to concatenate some text before it to make it a good label name. Thank you! – user9683851 Apr 23 '18 at 05:28

2 Answers2

1

Most assemblers allow local labels like this:

.macro do_work_if_value_not_zero 
    li s0, value
    bne s0, zero, 1f     # 1f means branch forward to the next label '1:'
    nop   

    // Do work

    1:
.endm

From the MIPS assembler manual here:

A generated label is a single numeric value (1...255). To reference a generated label, put an f (forward) or a b (backward) immediately after the digit. The reference tells the assembler to look for the nearest generated label that corresponds to the number in the lexically forward or backward direction.

markgz
  • 6,054
  • 1
  • 19
  • 41
0

@markgz's answer is the best one

I will keep this answer up in case an alternative solution is needed


The issue here is that value can't be used as a label as it is a number. As such, it likely doesn't contain the line number that we would like to jump to.

There are two solutions to this problem.

First

We can concatenate text to value in order to make it a proper label name like so

exitLabel\value :

Second (Courtesy of @Christian Gibbons)

We can add another parameter to specify the label name like so

.macro do_work_if_value_not_zero value exitLabelName
    ...
    ...
\exitLabelName :

This solution means that one can call the macro with the same parameters multiple times unlike the first solution which is limited to only unique calls to the macro.