Skip to content

Commit 0cea24a

Browse files
committed
[Clang][LoongArch] Add inline asm support for the q constraint
This patch adds support for the `q` constraint: a general-purpose register except for $r0 and $r1 (for the csrxchg instruction) Link: https://gcc.gnu.org/pipermail/gcc-patches/2025-May/684339.html
1 parent 4e186f2 commit 0cea24a

File tree

4 files changed

+27
-0
lines changed

4 files changed

+27
-0
lines changed

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ bool LoongArchTargetInfo::validateAsmConstraint(
139139
// A signed 16-bit constant.
140140
Info.setRequiresImmediate(-32768, 32767);
141141
return true;
142+
case 'q':
143+
// A general-purpose register except for $r0 and $r1 (for the csrxchg
144+
// instruction)
145+
Info.setAllowsRegister();
146+
return true;
142147
case 'I':
143148
// A signed 12-bit constant (for arithmetic instructions).
144149
Info.setRequiresImmediate(-2048, 2047);

clang/test/CodeGen/LoongArch/inline-asm-constraints.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ void test_m(int *p) {
3535
asm volatile("" :: "m"(*(p+4)));
3636
}
3737

38+
void test_q(void) {
39+
// CHECK-LABEL: define{{.*}} void @test_q()
40+
// CHECK: call void asm sideeffect "", "q"(i32 0)
41+
asm volatile ("" :: "q"(0));
42+
}
43+
3844
void test_I(void) {
3945
// CHECK-LABEL: define{{.*}} void @test_I()
4046
// CHECK: call void asm sideeffect "", "I"(i32 2047)

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7276,6 +7276,8 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
72767276
// 'm': A memory operand whose address is formed by a base register and
72777277
// offset that is suitable for use in instructions with the same
72787278
// addressing mode as st.w and ld.w.
7279+
// 'q': A general-purpose register except for $r0 and $r1 (for the csrxchg
7280+
// instruction)
72797281
// 'I': A signed 12-bit constant (for arithmetic instructions).
72807282
// 'J': Integer zero.
72817283
// 'K': An unsigned 12-bit constant (for logic instructions).
@@ -7289,6 +7291,7 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
72897291
default:
72907292
break;
72917293
case 'f':
7294+
case 'q':
72927295
return C_RegisterClass;
72937296
case 'l':
72947297
case 'I':
@@ -7328,6 +7331,8 @@ LoongArchTargetLowering::getRegForInlineAsmConstraint(
73287331
if (VT.isVector())
73297332
break;
73307333
return std::make_pair(0U, &LoongArch::GPRRegClass);
7334+
case 'q':
7335+
return std::make_pair(0U, &LoongArch::GPRNoR0R1RegClass);
73317336
case 'f':
73327337
if (Subtarget.hasBasicF() && VT == MVT::f32)
73337338
return std::make_pair(0U, &LoongArch::FPR32RegClass);

llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ define i32 @constraint_r(i32 %a, i32 %b) nounwind {
1717
ret i32 %1
1818
}
1919

20+
define i32 @constraint_q(i32 %a, i32 %b) nounwind {
21+
; CHECK-LABEL: constraint_q:
22+
; CHECK: # %bb.0:
23+
; CHECK-NEXT: #APP
24+
; CHECK-NEXT: csrxchg $a0, $a0, $a1
25+
; CHECK-NEXT: #NO_APP
26+
; CHECK-NEXT: ret
27+
%1 = tail call i32 asm "csrxchg $0, $1, $2", "=r,r,q,i"(i32 %a, i32 %b, i32 0)
28+
ret i32 %1
29+
}
30+
2031
define i32 @constraint_i(i32 %a) nounwind {
2132
; CHECK-LABEL: constraint_i:
2233
; CHECK: # %bb.0:

0 commit comments

Comments
 (0)