Are there assembly .macro differences in clang-cl.exe?

(Please move me if there is a better place?)

So we are trying to include some assembly between Linux, macOS and Windows (under clang),
and things work on the first two, but for Windows I get:

`
Windows compile (clang version 12.0.0 Target: i686-pc-windows-msvc)

clang -cc1as : fatal error : error in backend: unable to evaluate offset for variable ‘breg’`

When using code like:

    bytereg \TMP1
    movb    (\END_READ_LOCATION), breg

.macro bytereg reg
.if \reg == %r8 || \reg == %r9 || \reg == %r10 || \reg == %r11 || \reg
== %r12 || \reg == %r13 || \reg == %r14 || \reg == %r15
.set breg, \reg()b
.elseif \reg == %rax
.set breg, %al
.elseif \reg == %rcx
.set breg, %cl
.elseif \reg == %rdx
.set breg, %dl
.elseif \reg == %rbx
.set breg, %bl
.elseif \reg == rsp
.set breg, %spl
.elseif \reg == %rbp
.set breg, %bpl
.elseif \reg == rsi
.set breg, %sil
.elseif \reg == rdi
.set breg, %dil
.else
.error “Invalid register ‘\reg()’ while expanding macro ‘byter
eg()’”
.endif
.endm

I assume then it’s related to some Window-compat code? or I’m holding it on the wrong end? Is there a flag to make clang behave like expected?

Please advice,

Unrelated, but macOS had an amusing thing where .rept ; add $16, %r12 would become “6”, $1 parsed out as something else. “add $(16), %r12” works. I assume some Darwin history there.

Can you provide an example source file and clang / clang-cl invocations which demonstrate the problem?

As it is right now, it’s large. But I can probably pare down to a simpler test.

Thanks! Based on that, here’s a short repro:

$ cat /tmp/a.s
test:
  .set breg, %al
  movb 0, breg

$ clang -c /tmp/a.s
(okay)

$ clang -target x86_64-pc-win32 -c /tmp/a.s
<unknown>:0: error: expression could not be evaluated
clang -cc1as: fatal error: error in backend: unable to evaluate offset for variable 'breg'

The issue is that the code uses the breg symbol like a macro, but on Windows the assembler also tries to emit the symbol itself, which fails because its value is a register.

I don’t know why this is different from non-Windows. Maybe @pcc knows?

In any case, you can sneak past this error by using the private prefix “.L” on the symbol, so .Lbreg instead of just breg.