Paul S schrieb:
I've ported gcc to a 16 bit CPU and have all torture tests passing bar
one, pr52286.c
The offending lines of code are
long a, b = 0;
asm ("" : "=r" (a) : "0" (0));
which should cause zero to be assigned to the "a" SI sized variable.
Inspecting the generated code revealed that zero was only being assigned
to the lower 16 bit half of "a".
ld r2,0
I changed the inline asm statement to
asm ("" : "=r" (a) : "0" (0L));
(note the change 0 to 0L) which caused the correct code to be generated ...
ld r2,0
ld r3,0
Curious, I performed an RTL dump and found that without the trailing 'L'
following the '0' the output of the expand pass looks like this ...
(insn 6 5 7 2 (set (reg:SI 29 [ a ])
(asm_operands:SI ("") ("=r") 0 [
(reg:HI 30)
]
[
(asm_input:HI ("0")
../gcc/testsuite/gcc.c-torture/execute/pr52286.c:14)
]
compared to
(insn 6 5 7 2 (set (reg:SI 29 [ a ])
(asm_operands:SI ("") ("=r") 0 [
(reg:SI 30)
]
[
(asm_input:SI ("0")
../gcc/testsuite/gcc.c-torture/execute/pr52286.c:14)
]
when 0L is used instead of just 0.
so it seems that the "0" constraint on the input operand is affecting
the inferred mode of the output register operand ?
The 0 will we word_mode, presumably HImode on your machine, whereas
0L is long (obviously SImode on your machine).
The "0" constraint only tells the register allocator to use the same
reg, hence if you use (int)0 and ar eon littel endian, only the
lower 2 bytes will be set and the upper 2 bytes undefined.
Am I reading this correctly or have I missed something ?
Thanks, Paul
No, there are many test cases that are just dumped into the test
suite without proper review, so you can expect fallout when you
target has 16-bit int.
Johann