Index: lib/Target/RISCV/RISCVAsmPrinter.cpp =================================================================== --- lib/Target/RISCV/RISCVAsmPrinter.cpp +++ lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -92,20 +92,37 @@ if (!AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, 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; } Index: test/CodeGen/RISCV/inline-asm.ll =================================================================== --- test/CodeGen/RISCV/inline-asm.ll +++ test/CodeGen/RISCV/inline-asm.ll @@ -107,4 +107,49 @@ ret void } +define i32 @modifier_z_zero(i32 %a) { +; 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) { +; 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) { +; 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) { +; 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