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

Enhancement: allow expressions for immediate values and numeric directives .byte, .half, .word, .dword, etc. #217

Open
houghtonap opened this issue Apr 6, 2024 · 0 comments

Comments

@houghtonap
Copy link

Enhancement Request

Allow expressions where immediate values are expected and where a value is expected for numeric directives such as .byte, .half, .word, .dword, etc.

Background

RARS like many other assemblers allows one to define constants with an .eqv, .equ or .define directive. Those constants can be used for immediate values in the assembly code. Consider the following RISC-V assembly code:

.eqv    Mask    0xf
.text
        li      a0, Mask

RARS processes .eqv directive for Mask which results in the replacement of Mask with its value 0xf. After .eqv processing the RISC-V assembly code becomes:

.eqv    Mask    0xf
.text
        li      a0, 0xf

and is then compiled to executable form.

While developing an application there are times where you may need to combine values from different constants to generate an immediate value at assembly/compile time. Consider the following:

.eqv    BytesPerWord    4
.eqv    NumWords        2
.eqv    Mask1           0x00f
.eqv    Mask2           0xf00
.eqv    Mask3           ~ ( Mask1 | Mask2 )
 .text
        li  a0, Mask1 | Mask2              # does not work in RARS
        li  a0, Mask3                      # does not work in RARS
        li  a0, BytesPerWord * NumWords    # does not work in RARS

This need to calculate values also extends to the definition of numeric directives such as .byte, .half, .word, .dword, etc. There are times where you may want to calculate the size of a chunk of data memory and place that value in a .byte, .half, .word, .dword, etc. at assembly/compile time. Consider the following:

.macro  asciib  %label%, %string%
        .data
        .align  4
        .byte   %label%$end - %label%      # does not work in RARS
%label%:
        .ascii  %string%
        .align  4
%label%$end:
.end_macro

.macro  asciih  %label%, %string%
        .data
        .align  4
        .half  %label%$end - %label%       # does not work in RARS
%label%:
        .ascii  %string%
        .align  4
%label%$end:
.end_macro

.macro  asciiw  %label%, %string%
        .data
        .align  4
        .word  %label%$end - %label%       # does not work in RARS
%label%:
        .ascii  %string%
        .align  4
%label%$end:
.end_macro

The above technique is applicable for calculating the size of application defined "structures" that are comprised of varying data defining directives.

Basic Proposal

Allow basic C language style expressions, with the same operator precedence, where ever an immediate value is expected or when ever a value is expected for a numeric type directives such as .byte, .half, .word, .dword, etc.:

  1. Allow parentheses for grouping.
  2. Allow unary plus, unary minus, bitwise not (~), logical not (!).
  3. Allow multiplication (*), division (/), remainder (%).
  4. Allow addition (+), subtraction (-).
  5. Allow bitwise logical left shift (<<), logical right shift (>>), arithmetic right shift (>>>).
  6. Allow bitwise operator and (&).
  7. Allow bitwise operator xor (^).
  8. Allow bitwise operator or (|).

Extended Proposal

Ideally it would also be nice to include the following C language operators to allow one to create conditional constants at assembly/compile time:

  1. Allow relational operators <, <=, >, >=
  2. Allow relational equality operators ==, !=
  3. Allow logical and (&&).
  4. Allow logical or (||)
  5. Allow ternary conditional (?:)

Proposal Notes

  1. Expression calculations should not occur in the .eqv directive, only when the immediate value is expected or when a value is expected for a numeric type directive. Consider the following and its implications:

    .eqv    Mask1           0x00f
    .eqv    Mask2           0xf00
    .eqv    Mask3           ~ ( Mask1 | Mask2 )
     .text
            li  a0, Mask3

    The proposal implies that the above code first expand the .eqv directive for Mask3 and evaluate to:

    .eqv    Mask1           0x00f
    .eqv    Mask2           0xf00
    .eqv    Mask3           ~ ( Mask1 | Mask2 )
     .text
            li  a0, ~ ( Mask1 | Mask2 )

    then expand the .eqv directive for Mask1 and Mask2 and evaluate to:

    .eqv    Mask1           0x00f
    .eqv    Mask2           0xf00
    .eqv    Mask3           ~ ( Mask1 | Mask2 )
     .text
            li  a0, ~ ( 0x00f | 0xf00 )

    then after .eqv directive processing is complete, the expression is calculated to produce the final 0xfffff0f0 value for the li instruction and evaluate to:

    .eqv    Mask1           0x00f
    .eqv    Mask2           0xf00
    .eqv    Mask3           ~ ( Mask1 | Mask2 )
     .text
            li  a0, 0xfffff0f0

    This order of evaluation is necessary because under the proposal the following code, should also produce the same 0xfffff0f0 value for the li instruction when no .eqv directive is used:

     .text
            li  a0, ~ ( 0x00f | 0xf00 )

    or when .eqv directives are mixed with expression syntax as in the following code, which should also produce the same 0xfffff0f0 value for the li instruction:

    .eqv    Mask1           0x00f
    .eqv    Mask2           0xf00
     .text
            li  a0, ~ ( Mask1 | Mask2 )
  2. The proposal does not imply that the semantics of the .eqv directive change. Currently the application of the .eqv directive would have evaluated to the following code, then RARS would have issued an error in the messages pane since the immediate value for the li instruction was not a decimal or hexadecimal number.

    .eqv    Mask1           0x00f
    .eqv    Mask2           0xf00
    .eqv    Mask3           ~ ( Mask1 | Mask2 )
     .text
            li  a0, ~ ( 0x00f | 0xf00 )
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