Skip to content

Commit

Permalink
[Clang][LoongArch] Support inline asm constraint 'J'
Browse files Browse the repository at this point in the history
  • Loading branch information
SixWeining committed Oct 31, 2022
1 parent bd28a0a commit cd0174a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 0 deletions.
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/LoongArch.cpp
Expand Up @@ -88,6 +88,10 @@ bool LoongArchTargetInfo::validateAsmConstraint(
// A signed 12-bit constant (for arithmetic instructions).
Info.setRequiresImmediate(-2048, 2047);
return true;
case 'J':
// Integer zero.
Info.setRequiresImmediate(0);
return true;
case 'K':
// An unsigned 12-bit constant (for logic instructions).
Info.setRequiresImmediate(0, 4095);
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CodeGen/LoongArch/inline-asm-constraints.c
Expand Up @@ -43,6 +43,12 @@ void test_I(void) {
asm volatile ("" :: "I"(-2048));
}

void test_J(void) {
// CHECK-LABEL: define{{.*}} void @test_J()
// CHECK: call void asm sideeffect "", "J"(i32 0)
asm volatile ("" :: "J"(0));
}

void test_K(void) {
// CHECK-LABEL: define{{.*}} void @test_K()
// CHECK: call void asm sideeffect "", "K"(i32 4095)
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Expand Up @@ -2184,6 +2184,7 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
// offset that is suitable for use in instructions with the same
// addressing mode as st.w and ld.w.
// 'I': A signed 12-bit constant (for arithmetic instructions).
// 'J': Integer zero.
// 'K': An unsigned 12-bit constant (for logic instructions).
// "ZB": An address that is held in a general-purpose register. The offset is
// zero.
Expand All @@ -2198,6 +2199,7 @@ LoongArchTargetLowering::getConstraintType(StringRef Constraint) const {
return C_RegisterClass;
case 'l':
case 'I':
case 'J':
case 'K':
return C_Immediate;
case 'k':
Expand Down Expand Up @@ -2301,6 +2303,13 @@ void LoongArchTargetLowering::LowerAsmOperandForConstraint(
DAG.getTargetConstant(CVal, SDLoc(Op), Subtarget.getGRLenVT()));
}
return;
case 'J':
// Validate & create an integer zero operand.
if (auto *C = dyn_cast<ConstantSDNode>(Op))
if (C->getZExtValue() == 0)
Ops.push_back(
DAG.getTargetConstant(0, SDLoc(Op), Subtarget.getGRLenVT()));
return;
case 'K':
// Validate & create a 12-bit unsigned immediate operand.
if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
Expand Down
6 changes: 6 additions & 0 deletions llvm/test/CodeGen/LoongArch/inline-asm-constraint-error.ll
Expand Up @@ -17,6 +17,12 @@ define void @constraint_I() {
ret void
}

define void @constraint_J() {
; CHECK: error: value out of range for constraint 'J'
tail call void asm sideeffect "addi.w $$a0, $$a0, $$0", "J"(i32 1)
ret void
}

define void @constraint_K() {
; CHECK: error: value out of range for constraint 'K'
tail call void asm sideeffect "andi.w $$a0, $$a0, $0", "K"(i32 4096)
Expand Down
11 changes: 11 additions & 0 deletions llvm/test/CodeGen/LoongArch/inline-asm-constraint.ll
Expand Up @@ -58,6 +58,17 @@ define void @constraint_I() nounwind {
ret void
}

define void @constraint_J() nounwind {
; CHECK-LABEL: constraint_J:
; CHECK: # %bb.0:
; CHECK-NEXT: #APP
; CHECK-NEXT: addi.w $a0, $a0, 0
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
tail call void asm sideeffect "addi.w $$a0, $$a0, $0", "J"(i32 0)
ret void
}

define void @constraint_K() nounwind {
; CHECK-LABEL: constraint_K:
; CHECK: # %bb.0:
Expand Down

0 comments on commit cd0174a

Please sign in to comment.