Closed Bug 676308 Opened 11 years ago Closed 11 years ago

clang doesn't support ARM inline asm syntax in js_DoubleToECMAInt32


(Core :: JavaScript Engine, defect)

Not set





(Reporter: jchen, Unassigned)



Clang doesn't support the %R4 and %Q4 syntax used js_DoubleToECMAInt32, which denote upper/lower 32-bits of a 64-bit operand. A Google search suggests these are undocumented GCC features.

I'm inclined to think it's a clang bug since clang tries to emulate GCC, in which case I'll file a clang bug and close this one.

However, I think it'd be even better if there is an alternative syntax that we can use.
It is an llvm issue. Can you open the bug in and cc me?

gas can assemble a file with just "mov     r0, %R4, LSR #20", bug llvm-mc cannot:

llvm-mc -triple arm-none-linux-gnueabi test.s -filetype=obj
test.s:7:17: error: unexpected token in operand
	   mov     r0, %R4, LSR #20

you might be able to work around the problem by using -no-integrated-as.
Sorry, it is actually a problem in clang, not llvm. Looking a bit more, but a test that fails is

void f(void) {
  int i;
  asm ("   mov     %Q0, %Q0, LSL #20\n": "=r" (i)  );
gcc source code has a comment explaining it:

/* An explanation of the 'Q', 'R' and 'H' register operands:

	 In a pair of registers containing a DI or DF value the 'Q'
	 operand returns the register number of the register containing
	 the least significant part of the value.  The 'R' operand returns
	 the register number of the register containing the most
	 significant part of the value.

	 The 'H' operand returns the higher of the two register numbers.
	 On a run where WORDS_BIG_ENDIAN is true the 'H' operand is the
	 same as the 'Q' operand, since the most significant part of the
	 value is held in the lower number register.  The reverse is true
	 on systems where WORDS_BIG_ENDIAN is false.

	 The purpose of these operands is to distinguish between cases
	 where the endian-ness of the values is important (for example
	 when they are added together), and cases where the endian-ness
	 is irrelevant, but the order of register operations is important.
	 For example when loading a value from memory into a register
	 pair, the endian-ness does not matter.  Provided that the value
	 from the lower memory address is put into the lower numbered
	 register, and the value from the higher address is put into the
	 higher numbered register, the load will work regardless of whether
	 the value being loaded is big-wordian or little-wordian.  The
	 order of the two register loads can matter however, if the address
	 of the memory location is actually held in one of the registers
	 being overwritten by the load.

	 The 'Q' and 'R' constraints are also available for 64-bit
	 constants.  */

double f(double x) {
  asm ("mov     %R0, #4\n": "=&r" (x) );
  return x;
double g(double x) {
  asm ("mov     %Q0, #4\n": "=&r" (x) );
  return x;
double h(double x) {
  asm ("mov     %H0, #4\n": "=&r" (x) );
  return x;

for these inline asms, gcc produces:
        mov     r1, #4
       mov     r0, #4
        mov     r1, #4
This should be fixed in clang 137217. Can you confirm?
Confirmed fixed in latest clang.
Closed: 11 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.