invalid 'asm': invalid operand for code 'H'

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Mon Jul 9 09:53:00 GMT 2018


On 09/07/18 10:37, Richard Earnshaw (lists) wrote:
> On 08/07/18 06:03, Jeffrey Walton wrote:
>> Hi Everyone,
>>
>> I'm working from an ARM guide. The doc provides this code:
>>
>> $ cat move.c
>> int main(int argc, char* argv[])
>> {
>>     int a;
>>     asm volatile("movw %0,%L1 \n"
>>                  "movt %0,%H1 \n"
>>                  : "=r"(a) : "i"(0x12345678));
>>     return a;
>> }
>>
>> It results in:
>>
>> $ gcc -march=armv7 move.c
>> move.c: In function ‘main’:
>> move.c:4:5: error: invalid 'asm': invalid operand for code 'H'
>>      asm volatile("movw %0,%L1 \n"
>>      ^
>>
>> The guide says this about the modifiers:
>>
>> L - The lowest-numbered register of a register pair, or the low 16
>> bits of an immediate constant.
>> H - The highest-numbered register of a register pair, or the high 16
>> bits of an immediate constant
>> ....
>>
>> Is this an ARM extension not present in GCC? Or am I doing something wrong?
>>
>> Jeff
>>
> 
> The L and H modifiers are for dealing with 64-bit /register/ quantities
> where you need two registers to hold the entire value.  Your example
> only has a single 32-bit value.  You don't need qualifiers in this case.
>  For an immediate like this, you'll have to hand-code the reduction into
> the appropriate fields, either in the operands you pass to the ASM or
> within the ASM expansion itself.  Something like:
> 
> asm volatile ("movw %0, %1;movt %0, %2": "=r"(a) : "i"(imm & 0xffff),
> "i" (imm & 0xffff0000));
> 
> R.
> 

Correction.  Looking at the source code, the L modifier only appears to
apply to 32-bit integer immediate values, the H modifier only appears to
apply  to 64-bit registers.

So the guide is wrong for both cases, but in different ways.  At least
when it comes to GCC.

Which document are you referring to?

R.



More information about the Gcc-help mailing list