summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/InlineAsm.h1
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp3
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp17
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.h3
-rw-r--r--llvm/test/CodeGen/RISCV/inline-asm.ll25
5 files changed, 49 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/InlineAsm.h b/llvm/include/llvm/IR/InlineAsm.h
index 2aac807623a..72d8ad1501a 100644
--- a/llvm/include/llvm/IR/InlineAsm.h
+++ b/llvm/include/llvm/IR/InlineAsm.h
@@ -244,6 +244,7 @@ public:
Constraint_m,
Constraint_o,
Constraint_v,
+ Constraint_A,
Constraint_Q,
Constraint_R,
Constraint_S,
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index d0a3af375a6..8439278b4ed 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -179,6 +179,9 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
// operand and need no special handling.
OutOps.push_back(Op);
return false;
+ case InlineAsm::Constraint_A:
+ OutOps.push_back(Op);
+ return false;
default:
break;
}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index e822b521fc0..a9c4b69927b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2437,6 +2437,8 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
case 'J':
case 'K':
return C_Immediate;
+ case 'A':
+ return C_Memory;
}
}
return TargetLowering::getConstraintType(Constraint);
@@ -2556,6 +2558,21 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
}
+unsigned
+RISCVTargetLowering::getInlineAsmMemConstraint(StringRef ConstraintCode) const {
+ // Currently only support length 1 constraints.
+ if (ConstraintCode.size() == 1) {
+ switch (ConstraintCode[0]) {
+ case 'A':
+ return InlineAsm::Constraint_A;
+ default:
+ break;
+ }
+ }
+
+ return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
+}
+
void RISCVTargetLowering::LowerAsmOperandForConstraint(
SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops,
SelectionDAG &DAG) const {
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index f28c4753c1d..e2059e70831 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -93,6 +93,9 @@ public:
const char *getTargetNodeName(unsigned Opcode) const override;
ConstraintType getConstraintType(StringRef Constraint) const override;
+
+ unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
+
std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint, MVT VT) const override;
diff --git a/llvm/test/CodeGen/RISCV/inline-asm.ll b/llvm/test/CodeGen/RISCV/inline-asm.ll
index 10f8a3452ab..39403360215 100644
--- a/llvm/test/CodeGen/RISCV/inline-asm.ll
+++ b/llvm/test/CodeGen/RISCV/inline-asm.ll
@@ -150,6 +150,31 @@ define void @constraint_K() nounwind {
ret void
}
+define void @constraint_A(i8* %a) nounwind {
+; RV32I-LABEL: constraint_A:
+; RV32I: # %bb.0:
+; RV32I-NEXT: #APP
+; RV32I-NEXT: sb s0, 0(a0)
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: #APP
+; RV32I-NEXT: lb s1, 0(a0)
+; RV32I-NEXT: #NO_APP
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: constraint_A:
+; RV64I: # %bb.0:
+; RV64I-NEXT: #APP
+; RV64I-NEXT: sb s0, 0(a0)
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: #APP
+; RV64I-NEXT: lb s1, 0(a0)
+; RV64I-NEXT: #NO_APP
+; RV64I-NEXT: ret
+ tail call void asm sideeffect "sb s0, $0", "*A"(i8* %a)
+ tail call void asm sideeffect "lb s1, $0", "*A"(i8* %a)
+ ret void
+}
+
define i32 @modifier_z_zero(i32 %a) nounwind {
; RV32I-LABEL: modifier_z_zero:
; RV32I: # %bb.0:
OpenPOWER on IntegriCloud