Porting an oddball assembler

We’re attempting to port a bespoke assembler to LLVM MC. We are tentatively willing to rewrite some assembly code to deal with simple issues of syntax, but there are some features that don’t appear to translate easily.

The first is like NASM-style “inline macros”:

.define MYNUM = 1
.define MYEXPR(a, b) = $a + $b  ; We could change this syntax to use \a and \b.

add r1, r2, MYNUM
add r2, r3, MYEXPR(x, y)  ; Expands to add r2, r3, x + y where "x + y" is evaluated to a constant

AFAIK LLVM MC’s macro capability is the same as GNU as and macro expansion is only allowed in a “full statement” context. We can, I think, reasonably implement our own target-specific symbol table for these things, but I’m not sure how to get them substituted at use. It really is a textual substitution, so uses could appear almost anywhere.

This oddball assembler also supports namespaces:

.scope a
  .const ten = 10
  .const foo = b.bar  ; Will be resolved later.
.end_scope

.scope b
  .const bar = 12
.end_scope

add r1, r2, a.ten
add r2, r2, b.bar

Yes, this assembler is indeed too fancy for its own good. And “scope” is a misnomer.

One option for the namespacing is to parse the target-specific scope directives and somehow mangle the names upon reference before entering them in LLVM’s symbol table. Is there some target hook that allows such mangling? I see that MCAsmParser::parseIdentifier is virtual. It seems overkill for what we need to do (a target hook to mangle the name would be nicer). Are there other options?

Does anyone have experience with such things in LLVM MC? Any advice would be greatly appreciated!

David