forked from OSchip/llvm-project
[RISCV] Lower inline asm constraint A for RISC-V
This allows arguments with the constraint A to be lowered to input nodes for RISC-V, which implies a memory address stored in a register. This patch adds the minimal amount of code required to get operands with the right constraints to compile. https://reviews.llvm.org/D54296 llvm-svn: 369095
This commit is contained in:
parent
59894d4668
commit
7abf863f76
|
@ -244,6 +244,7 @@ public:
|
||||||
Constraint_m,
|
Constraint_m,
|
||||||
Constraint_o,
|
Constraint_o,
|
||||||
Constraint_v,
|
Constraint_v,
|
||||||
|
Constraint_A,
|
||||||
Constraint_Q,
|
Constraint_Q,
|
||||||
Constraint_R,
|
Constraint_R,
|
||||||
Constraint_S,
|
Constraint_S,
|
||||||
|
|
|
@ -179,6 +179,9 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
|
||||||
// operand and need no special handling.
|
// operand and need no special handling.
|
||||||
OutOps.push_back(Op);
|
OutOps.push_back(Op);
|
||||||
return false;
|
return false;
|
||||||
|
case InlineAsm::Constraint_A:
|
||||||
|
OutOps.push_back(Op);
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2437,6 +2437,8 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
|
||||||
case 'J':
|
case 'J':
|
||||||
case 'K':
|
case 'K':
|
||||||
return C_Immediate;
|
return C_Immediate;
|
||||||
|
case 'A':
|
||||||
|
return C_Memory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TargetLowering::getConstraintType(Constraint);
|
return TargetLowering::getConstraintType(Constraint);
|
||||||
|
@ -2556,6 +2558,21 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
|
||||||
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
|
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(
|
void RISCVTargetLowering::LowerAsmOperandForConstraint(
|
||||||
SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops,
|
SDValue Op, std::string &Constraint, std::vector<SDValue> &Ops,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
|
|
|
@ -93,6 +93,9 @@ public:
|
||||||
const char *getTargetNodeName(unsigned Opcode) const override;
|
const char *getTargetNodeName(unsigned Opcode) const override;
|
||||||
|
|
||||||
ConstraintType getConstraintType(StringRef Constraint) const override;
|
ConstraintType getConstraintType(StringRef Constraint) const override;
|
||||||
|
|
||||||
|
unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
|
||||||
|
|
||||||
std::pair<unsigned, const TargetRegisterClass *>
|
std::pair<unsigned, const TargetRegisterClass *>
|
||||||
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
|
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
|
||||||
StringRef Constraint, MVT VT) const override;
|
StringRef Constraint, MVT VT) const override;
|
||||||
|
|
|
@ -150,6 +150,31 @@ define void @constraint_K() nounwind {
|
||||||
ret void
|
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 {
|
define i32 @modifier_z_zero(i32 %a) nounwind {
|
||||||
; RV32I-LABEL: modifier_z_zero:
|
; RV32I-LABEL: modifier_z_zero:
|
||||||
; RV32I: # %bb.0:
|
; RV32I: # %bb.0:
|
||||||
|
|
Loading…
Reference in New Issue