Skip to content

Conversation

statham-arm
Copy link
Collaborator

An inline asm constraint "Jr", in AArch32, means that if the input value is a compile-time constant in the range -4095 to +4095, then it can be inserted into the assembly language as an immediate operand, and otherwise it will be placed in a register.

The comment in the Arm backend said "It is not clear what this constraint is intended for". I believe the answer is that that range of immediate values are the ones you can use in a LDR or STR instruction. So it's suitable for cases like this:

asm("str %0,[%1,%2]" : : "r"(data), "r"(base), "Jr"(offset) : "memory");

in the same way that the "Ir" constraint is suitable for the immediate in a data-processing instruction such as ADD or EOR.

An inline asm constraint "Jr", in AArch32, means that if the input
value is a compile-time constant in the range -4095 to +4095, then it
can be inserted into the assembly language as an immediate operand,
and otherwise it will be placed in a register.

The comment in the Arm backend said "It is not clear what this
constraint is intended for". I believe the answer is that that range
of immediate values are the ones you can use in a LDR or STR
instruction. So it's suitable for cases like this:

  asm("str %0,[%1,%2]" : : "r"(data), "r"(base), "Jr"(offset) : "memory");

in the same way that the "Ir" constraint is suitable for the immediate
in a data-processing instruction such as ADD or EOR.
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2025

@llvm/pr-subscribers-backend-arm

Author: Simon Tatham (statham-arm)

Changes

An inline asm constraint "Jr", in AArch32, means that if the input value is a compile-time constant in the range -4095 to +4095, then it can be inserted into the assembly language as an immediate operand, and otherwise it will be placed in a register.

The comment in the Arm backend said "It is not clear what this constraint is intended for". I believe the answer is that that range of immediate values are the ones you can use in a LDR or STR instruction. So it's suitable for cases like this:

asm("str %0,[%1,%2]" : : "r"(data), "r"(base), "Jr"(offset) : "memory");

in the same way that the "Ir" constraint is suitable for the immediate in a data-processing instruction such as ADD or EOR.


Full diff: https://github.com/llvm/llvm-project/pull/160712.diff

1 Files Affected:

  • (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+3-3)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 9a247bb5a83d9..c283b0c77872e 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20428,9 +20428,9 @@ void ARMTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
           if (CVal >= -255 && CVal <= -1)
             break;
         } else {
-          // This must be a constant between -4095 and 4095. It is not clear
-          // what this constraint is intended for. Implemented for
-          // compatibility with GCC.
+          // This must be a constant between -4095 and 4095. This is suitable
+          // for use as the immediate offset field in LDR and STR instructions
+          // such as LDR r0,[r1,#offset].
           if (CVal >= -4095 && CVal <= 4095)
             break;
         }

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

The only reference I can find is the Arm inline assembly cookbook which has a table near to For ARM processors, GCC 4 provides the following constraints. in:
http://www.ethernut.de/en/documents/arm-inline-asm.html

It does mention a similar example to yours.

@statham-arm statham-arm merged commit 2cacf71 into llvm:main Sep 26, 2025
11 checks passed
@statham-arm statham-arm deleted the comment-Jr branch September 26, 2025 08:19
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
An inline asm constraint "Jr", in AArch32, means that if the input value
is a compile-time constant in the range -4095 to +4095, then it can be
inserted into the assembly language as an immediate operand, and
otherwise it will be placed in a register.

The comment in the Arm backend said "It is not clear what this
constraint is intended for". I believe the answer is that that range of
immediate values are the ones you can use in a LDR or STR instruction.
So it's suitable for cases like this:

asm("str %0,[%1,%2]" : : "r"(data), "r"(base), "Jr"(offset) : "memory");

in the same way that the "Ir" constraint is suitable for the immediate
in a data-processing instruction such as ADD or EOR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants