Skip to content

Commit cd0174a

Browse files
committed
[Clang][LoongArch] Support inline asm constraint 'J'
'J' is defined in GCC [1] but not documented [2] while Linux [3] has already used it in LoongArch port. [1]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/constraints.md#L61 [2]: https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html [3]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/asm/cmpxchg.h#L19 Differential Revision: https://reviews.llvm.org/D136835
1 parent bd28a0a commit cd0174a

File tree

5 files changed

+36
-0
lines changed

5 files changed

+36
-0
lines changed

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ bool LoongArchTargetInfo::validateAsmConstraint(
8888
// A signed 12-bit constant (for arithmetic instructions).
8989
Info.setRequiresImmediate(-2048, 2047);
9090
return true;
91+
case 'J':
92+
// Integer zero.
93+
Info.setRequiresImmediate(0);
94+
return true;
9195
case 'K':
9296
// An unsigned 12-bit constant (for logic instructions).
9397
Info.setRequiresImmediate(0, 4095);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ void test_I(void) {
4343
asm volatile ("" :: "I"(-2048));
4444
}
4545

46+
void test_J(void) {
47+
// CHECK-LABEL: define{{.*}} void @test_J()
48+
// CHECK: call void asm sideeffect "", "J"(i32 0)
49+
asm volatile ("" :: "J"(0));
50+
}
51+
4652
void test_K(void) {
4753
// CHECK-LABEL: define{{.*}} void @test_K()
4854
// CHECK: call void asm sideeffect "", "K"(i32 4095)

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,7 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
21842184
// offset that is suitable for use in instructions with the same
21852185
// addressing mode as st.w and ld.w.
21862186
// 'I': A signed 12-bit constant (for arithmetic instructions).
2187+
// 'J': Integer zero.
21872188
// 'K': An unsigned 12-bit constant (for logic instructions).
21882189
// "ZB": An address that is held in a general-purpose register. The offset is
21892190
// zero.
@@ -2198,6 +2199,7 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
21982199
return C_RegisterClass;
21992200
case 'l':
22002201
case 'I':
2202+
case 'J':
22012203
case 'K':
22022204
return C_Immediate;
22032205
case 'k':
@@ -2301,6 +2303,13 @@ void LoongArchTargetLowering::LowerAsmOperandForConstraint(
23012303
DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT()));
23022304
}
23032305
return;
2306+
case 'J':
2307+
// Validate & create an integer zero operand.
2308+
if (auto *C = dyn_cast<ConstantSDNode>(Op))
2309+
if (C->getZExtValue() == 0)
2310+
Ops.push_back(
2311+
DAG.getTargetConstant(0, SDLoc(Op), Subtarget.getGRLenVT()));
2312+
return;
23042313
case 'K':
23052314
// Validate & create a 12-bit unsigned immediate operand.
23062315
if (auto *C = dyn_cast<ConstantSDNode>(Op)) {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ define void @constraint_I() {
1717
ret void
1818
}
1919

20+
define void @constraint_J() {
21+
; CHECK: error: value out of range for constraint 'J'
22+
tail call void asm sideeffect "addi.w $$a0, $$a0, $$0", "J"(i32 1)
23+
ret void
24+
}
25+
2026
define void @constraint_K() {
2127
; CHECK: error: value out of range for constraint 'K'
2228
tail call void asm sideeffect "andi.w $$a0, $$a0, $0", "K"(i32 4096)

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ define void @constraint_I() nounwind {
5858
ret void
5959
}
6060

61+
define void @constraint_J() nounwind {
62+
; CHECK-LABEL: constraint_J:
63+
; CHECK: # %bb.0:
64+
; CHECK-NEXT: #APP
65+
; CHECK-NEXT: addi.w $a0, $a0, 0
66+
; CHECK-NEXT: #NO_APP
67+
; CHECK-NEXT: ret
68+
tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "J"(i32 0)
69+
ret void
70+
}
71+
6172
define void @constraint_K() nounwind {
6273
; CHECK-LABEL: constraint_K:
6374
; CHECK: # %bb.0:

0 commit comments

Comments
 (0)