diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -764,11 +764,18 @@ bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS) { - if (ExtraCode) - return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); + const MCRegisterInfo &MRI = *TM.getMCRegisterInfo(); + MachineOperand MO = MI->getOperand(OpNo); + if (ExtraCode) { + if (ExtraCode[0] == 'N' && !ExtraCode[1] && MO.isReg() && + SystemZ::GR128BitRegClass.contains(MO.getReg())) + MO.setReg(MRI.getSubReg(MO.getReg(), SystemZ::subreg_l64)); + else + return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS); + } SystemZMCInstLower Lower(MF->getContext(), *this); - MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); - SystemZInstPrinter::printOperand(MO, MAI, OS); + MCOperand MCOp(Lower.lowerOperand(MO)); + SystemZInstPrinter::printOperand(MCOp, MAI, OS); return false; } diff --git a/llvm/test/CodeGen/SystemZ/inline-asm-i128.ll b/llvm/test/CodeGen/SystemZ/inline-asm-i128.ll --- a/llvm/test/CodeGen/SystemZ/inline-asm-i128.ll +++ b/llvm/test/CodeGen/SystemZ/inline-asm-i128.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=s390x-linux-gnu -no-integrated-as < %s | FileCheck %s ; + ; Test i128 (tied) operands. define i32 @fun0(i8* %p1, i32 signext %l1, i8* %p2, i32 signext %l2, i8 zeroext %pad) { @@ -118,3 +119,19 @@ store volatile i128 %IAsm, i128* %Dst ret void } + +; Test access of the odd register using 'N'. +define i64 @fun5(i64 %b) { +; CHECK-LABEL: fun5: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lgr %r1, %r2 +; CHECK-NEXT: lghi %r0, 0 +; CHECK-NEXT: #APP +; CHECK-NEXT: lgr %r2,%r1 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: br %r14 +entry: + %Ins = zext i64 %b to i128 + %Res = tail call i64 asm "\09lgr\09$0,${1:N}", "=d,d"(i128 %Ins) + ret i64 %Res +}