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

Faulty behavior regarding const expressions in assembly #217

Open
xen0n opened this issue Mar 7, 2023 · 2 comments
Open

Faulty behavior regarding const expressions in assembly #217

xen0n opened this issue Mar 7, 2023 · 2 comments

Comments

@xen0n
Copy link

xen0n commented Mar 7, 2023

Minimized reproducer:

foo:
andi $a0, $a0, (0+(((~((0)))-(((1))<<(0))+1)&(~((0))>>(64-1-(9)))))

This is typical code pattern expanded from Linux's GENMASK(h, l) macro generating bitfield constants.

This breaks with current binutils-gdb main branch:

$ loongarch64-unknown-linux-gnu-gcc -c -o foo.o foo.s
foo.s: Assembler messages:
foo.s:2: Fatal error: Immediate overflow.
format: u10:12
arg: (0+(((~((0)))-(((1))<<(0))+1)&(~((0))>>(64-1-(9)))))

While the LLVM integrated assembler works:

$ clang-16 --target=loongarch64 -fintegrated-as -c -o foo.o foo.s
$ loongarch64-unknown-linux-gnu-objdump -d foo.o

foo.o:     file format elf64-loongarch


Disassembly of section .text:

0000000000000000 <foo>:
   0:   034ffc84        andi            $a0, $a0, 0x3ff
@xen0n
Copy link
Author

xen0n commented Mar 7, 2023

I've looked into this and unfortunately it seems a difficult one: the LoongArch expressions are evaluated with custom rules defined in gas/config/loongarch-parse.y, and >> is explicitly defined to arithmetically right shift. I tried to stick a plain my_getExpression inside loongarch_parse_expr's constant-value-result branch but it breaks a number of test cases; I'm not sure if any code in the wild is depending on the previous behavior, in which case this might be impossible to fix without breakage.

However, given LLVM has the intended behavior (hence users may already have to face behavioral differences), we may be able to break compatibility a little bit here in favor of doing things right. Opinions, folks?

@xry111
Copy link

xry111 commented Mar 14, 2023

The GAS manual says:

 ‘>>’
      “Shift Right”.  Same as the C operator ‘>>’.

But it's implementation-defined unspecified whether C operator '>>' should do signed extension or zero extension for signed integer types. Maybe we should add a new switch to control the behavior?

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

2 participants