[RISCV] Support z and i operand modifiers

Differential Revision: https://reviews.llvm.org/D57792
Patch by James Clarke.

llvm-svn: 365291
This commit is contained in:
Alex Bradbury 2019-07-08 05:00:26 +00:00
parent f814dcbafb
commit e1e036a33b
2 changed files with 72 additions and 9 deletions

View File

@ -87,20 +87,38 @@ bool RISCVAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
return false;
if (!ExtraCode) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
OS << MO.getImm();
return false;
case MachineOperand::MO_Register:
OS << RISCVInstPrinter::getRegisterName(MO.getReg());
return false;
const MachineOperand &MO = MI->getOperand(OpNo);
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0)
return true; // Unknown modifier.
switch (ExtraCode[0]) {
default:
return true; // Unknown modifier.
case 'z': // Print zero register if zero, regular printing otherwise.
if (MO.isImm() && MO.getImm() == 0) {
OS << RISCVInstPrinter::getRegisterName(RISCV::X0);
return false;
}
break;
case 'i': // Literal 'i' if operand is not a register.
if (!MO.isReg())
OS << 'i';
return false;
}
}
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
OS << MO.getImm();
return false;
case MachineOperand::MO_Register:
OS << RISCVInstPrinter::getRegisterName(MO.getReg());
return false;
default:
break;
}
return true;
}

View File

@ -150,4 +150,49 @@ define void @constraint_K() nounwind {
ret void
}
define i32 @modifier_z_zero(i32 %a) nounwind {
; RV32I-LABEL: modifier_z_zero:
; RV32I: # %bb.0:
; RV32I-NEXT: #APP
; RV32I-NEXT: add a0, a0, zero
; RV32I-NEXT: #NO_APP
; RV32I-NEXT: ret
%1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,r"(i32 %a, i32 0)
ret i32 %1
}
define i32 @modifier_z_nonzero(i32 %a) nounwind {
; RV32I-LABEL: modifier_z_nonzero:
; RV32I: # %bb.0:
; RV32I-NEXT: addi a1, zero, 1
; RV32I-NEXT: #APP
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: #NO_APP
; RV32I-NEXT: ret
%1 = tail call i32 asm "add $0, $1, ${2:z}", "=r,r,r"(i32 %a, i32 1)
ret i32 %1
}
define i32 @modifier_i_imm(i32 %a) nounwind {
; RV32I-LABEL: modifier_i_imm:
; RV32I: # %bb.0:
; RV32I-NEXT: #APP
; RV32I-NEXT: addi a0, a0, 1
; RV32I-NEXT: #NO_APP
; RV32I-NEXT: ret
%1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 1)
ret i32 %1
}
define i32 @modifier_i_reg(i32 %a, i32 %b) nounwind {
; RV32I-LABEL: modifier_i_reg:
; RV32I: # %bb.0:
; RV32I-NEXT: #APP
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: #NO_APP
; RV32I-NEXT: ret
%1 = tail call i32 asm "add${2:i} $0, $1, $2", "=r,r,ri"(i32 %a, i32 %b)
ret i32 %1
}
; TODO: expend tests for more complex constraints, out of range immediates etc