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.