10.4.6 Using multiple alternative operand constraints

There are many instructions that can take either an immediate value with limited range or a register as one of their operands.

To generate optimal code for an instruction, use the immediate version of the instruction where possible. Using an immediate value avoids needing a register to hold the operand, and any extra instructions to load the operand into that register. However, you can only use an immediate value if the operand is a compile-time constant, and is in the appropriate range.

To generate the best possible code, you can provide multiple constraint codes for an operand. The compiler selects the most restrictive one that it can use.

Example

int add(int a, int b) {
	int r;
	// Here, the "Ir" constraint string tells the compiler that operand b can be
	// an immediate, but if it is not a constant, or not in the appropriate
	// range for an arithmetic instruction, it can be placed in a register.
	__asm("add %[r], %[a], %[b]"
		: [r] "=r" (r)
		: [a] "r" (a),
		  [b] "Ir" (b));
	return r;
}

// At -O2 or above, the call to add will be inlined and optimised, so that the
// immediate form of the add instruction can be used.
int add_42(int a) {
	return add(a, 42);
}

// Here, the immediate is not usable by the add instruction, so the compiler
// emits a movw instruction to load the value 12345 into a register.
int add_12345(int a) {
	return add(a, 12345);
}
Non-ConfidentialPDF file icon PDF versionDUI0774J
Copyright © 2014–2017, 2019 Arm Limited or its affiliates. All rights reserved.