* invalid 'asm': invalid operand for code 'H'
@ 2018-07-08 5:03 Jeffrey Walton
2018-07-09 9:46 ` Richard Earnshaw (lists)
0 siblings, 1 reply; 7+ messages in thread
From: Jeffrey Walton @ 2018-07-08 5:03 UTC (permalink / raw)
To: gcc-help
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
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: invalid 'asm': invalid operand for code 'H'
2018-07-08 5:03 invalid 'asm': invalid operand for code 'H' Jeffrey Walton
@ 2018-07-09 9:46 ` Richard Earnshaw (lists)
2018-07-09 9:53 ` Richard Earnshaw (lists)
0 siblings, 1 reply; 7+ messages in thread
From: Richard Earnshaw (lists) @ 2018-07-09 9:46 UTC (permalink / raw)
To: noloader, gcc-help
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=us-ascii, Size: 1396 bytes --]
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.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: invalid 'asm': invalid operand for code 'H'
2018-07-09 9:46 ` Richard Earnshaw (lists)
@ 2018-07-09 9:53 ` Richard Earnshaw (lists)
2018-07-09 11:53 ` Jeffrey Walton
0 siblings, 1 reply; 7+ messages in thread
From: Richard Earnshaw (lists) @ 2018-07-09 9:53 UTC (permalink / raw)
To: noloader, gcc-help
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.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: invalid 'asm': invalid operand for code 'H'
2018-07-09 9:53 ` Richard Earnshaw (lists)
@ 2018-07-09 11:53 ` Jeffrey Walton
2018-07-09 12:48 ` U.Mutlu
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Jeffrey Walton @ 2018-07-09 11:53 UTC (permalink / raw)
To: Richard Earnshaw (lists); +Cc: gcc-help
On Mon, Jul 9, 2018 at 5:51 AM, Richard Earnshaw (lists)
<Richard.Earnshaw@arm.com> wrote:
> On 09/07/18 10:37, Richard Earnshaw (lists) wrote:
>> On 08/07/18 06:03, Jeffrey Walton wrote:
>>> ...
>>> 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?
>>>
>> 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));
>>
> 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?
Thanks Richard.
The guide I was using is
http://www.iarsys.co.jp/download/LMS2/arm/7304/ewarm7304doc/arm/doc/EWARM_DevelopmentGuide.ENU.pdf
(p.147).
Jeff
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: invalid 'asm': invalid operand for code 'H'
2018-07-09 11:53 ` Jeffrey Walton
@ 2018-07-09 12:48 ` U.Mutlu
2018-07-09 12:53 ` Richard Earnshaw (lists)
2018-07-09 16:57 ` Richard Earnshaw (lists)
2 siblings, 0 replies; 7+ messages in thread
From: U.Mutlu @ 2018-07-09 12:48 UTC (permalink / raw)
To: noloader, Richard Earnshaw (lists); +Cc: gcc-help
Jeffrey Walton wrote on 07/09/2018 12:49 PM:
> On Mon, Jul 9, 2018 at 5:51 AM, Richard Earnshaw (lists)
> <Richard.Earnshaw@arm.com> wrote:
>> On 09/07/18 10:37, Richard Earnshaw (lists) wrote:
>>> On 08/07/18 06:03, Jeffrey Walton wrote:
>>>> ...
>>>> 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?
>>>>
>>> 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));
>>>
>> 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?
>
> Thanks Richard.
>
> The guide I was using is
> http://www.iarsys.co.jp/download/LMS2/arm/7304/ewarm7304doc/arm/doc/EWARM_DevelopmentGuide.ENU.pdf
> (p.147).
I'm not an assembler guy, but a quick search revealed the following:
https://gcc.gnu.org/onlinedocs/gcc/Constraints.html
https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
(or in this case ../gcc_trunk/gcc/config/arm/constraints.md )
https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html
So, the said L and H modifiers of ARM seem not among the listed modifiers in
the 3nd link above.
As the table on the said page in the above pdf shows, there are many more
modifiers available that seem to be not implemented yet in gcc.
If modifying the source is an option, then one surely can find replacements,
like here:
https://stackoverflow.com/questions/7800055/movw-and-movt-in-arm-assembly
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: invalid 'asm': invalid operand for code 'H'
2018-07-09 11:53 ` Jeffrey Walton
2018-07-09 12:48 ` U.Mutlu
@ 2018-07-09 12:53 ` Richard Earnshaw (lists)
2018-07-09 16:57 ` Richard Earnshaw (lists)
2 siblings, 0 replies; 7+ messages in thread
From: Richard Earnshaw (lists) @ 2018-07-09 12:53 UTC (permalink / raw)
To: noloader; +Cc: gcc-help
On 09/07/18 11:49, Jeffrey Walton wrote:
> On Mon, Jul 9, 2018 at 5:51 AM, Richard Earnshaw (lists)
> <Richard.Earnshaw@arm.com> wrote:
>> On 09/07/18 10:37, Richard Earnshaw (lists) wrote:
>>> On 08/07/18 06:03, Jeffrey Walton wrote:
>>>> ...
>>>> 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?
>>>>
>>> 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));
>>>
>> 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?
>
> Thanks Richard.
>
> The guide I was using is
> http://www.iarsys.co.jp/download/LMS2/arm/7304/ewarm7304doc/arm/doc/EWARM_DevelopmentGuide.ENU.pdf
> (p.147).
>
> Jeff
>
There are a number of modifiers (and constraints) in GCC that we
deliberately don't document. Generally that's because we don't believe
they really serve a useful purpose for folk writing inline assembly
language. If we documented them then we would create a 'forever'
contract with users for very little real gain. By keeping them
undocumented we preserve the right to change the implementation or
definition if circumstances require that.
I suspect that's the real reason these are treated as hidden values.
Unfortunately, GCC does not really provide a useful distinction between
uses that are internal and uses that are in inline assembly.
R.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: invalid 'asm': invalid operand for code 'H'
2018-07-09 11:53 ` Jeffrey Walton
2018-07-09 12:48 ` U.Mutlu
2018-07-09 12:53 ` Richard Earnshaw (lists)
@ 2018-07-09 16:57 ` Richard Earnshaw (lists)
2 siblings, 0 replies; 7+ messages in thread
From: Richard Earnshaw (lists) @ 2018-07-09 16:57 UTC (permalink / raw)
To: noloader; +Cc: gcc-help
On 09/07/18 11:49, Jeffrey Walton wrote:
> On Mon, Jul 9, 2018 at 5:51 AM, Richard Earnshaw (lists)
> <Richard.Earnshaw@arm.com> wrote:
>> On 09/07/18 10:37, Richard Earnshaw (lists) wrote:
>>> On 08/07/18 06:03, Jeffrey Walton wrote:
>>>> ...
>>>> 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?
>>>>
>>> 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));
>>>
>> 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?
>
> Thanks Richard.
>
> The guide I was using is
> http://www.iarsys.co.jp/download/LMS2/arm/7304/ewarm7304doc/arm/doc/EWARM_DevelopmentGuide.ENU.pdf
> (p.147).
>
> Jeff
>
Just for the record, this is documentation for the IAR toolchain. They
have adopted the basic GCC syntax, but it would appear that they've then
extended the API beyond that which GCC implements. There's no guarantee
that anything written here will be compatible with GCC.
So, as they say, your mileage may vary.
R.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-07-09 12:53 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-08 5:03 invalid 'asm': invalid operand for code 'H' Jeffrey Walton
2018-07-09 9:46 ` Richard Earnshaw (lists)
2018-07-09 9:53 ` Richard Earnshaw (lists)
2018-07-09 11:53 ` Jeffrey Walton
2018-07-09 12:48 ` U.Mutlu
2018-07-09 12:53 ` Richard Earnshaw (lists)
2018-07-09 16:57 ` Richard Earnshaw (lists)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).