[LoongArch] Relax the restrictions of inlineasm operand modifier 'u' … · llvm/llvm-project@f09bcfb (original) (raw)

3 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -5826,6 +5826,8 @@ Hexagon:
5826 5826
5827 5827 LoongArch:
5828 5828
5829 +- ``u``: Print an LASX register.
5830 +- ``w``: Print an LSX register.
5829 5831 - ``z``: Print $zero register if operand is zero, otherwise print it normally.
5830 5832
5831 5833 MSP430:
Original file line number Diff line number Diff line change
@@ -90,20 +90,29 @@ bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
90 90 return false;
91 91 }
92 92 break;
93 -case 'w': // Print LSX registers.
94 -if (MO.getReg().id() >= LoongArch::VR0 &&
95 - MO.getReg().id() <= LoongArch::VR31)
96 -break;
97 -// The modifier is 'w' but the operand is not an LSX register; Report an
98 -// unknown operand error.
99 -return true;
100 93 case 'u': // Print LASX registers.
101 -if (MO.getReg().id() >= LoongArch::XR0 &&
102 - MO.getReg().id() <= LoongArch::XR31)
103 -break;
104 -// The modifier is 'u' but the operand is not an LASX register; Report an
105 -// unknown operand error.
106 -return true;
94 +case 'w': // Print LSX registers.
95 + {
96 +// If the operand is an LASX, LSX or floating point register, print the
97 +// name of LASX or LSX register with the same index in that register
98 +// class.
99 +unsigned RegID = MO.getReg().id(), FirstReg;
100 +if (RegID >= LoongArch::XR0 && RegID <= LoongArch::XR31)
101 + FirstReg = LoongArch::XR0;
102 +else if (RegID >= LoongArch::VR0 && RegID <= LoongArch::VR31)
103 + FirstReg = LoongArch::VR0;
104 +else if (RegID >= LoongArch::F0_64 && RegID <= LoongArch::F31_64)
105 + FirstReg = LoongArch::F0_64;
106 +else if (RegID >= LoongArch::F0 && RegID <= LoongArch::F31)
107 + FirstReg = LoongArch::F0;
108 +else
109 +return true;
110 + OS << '$'
111 + << LoongArchInstPrinter::getRegisterName(
112 + RegID - FirstReg +
113 + (ExtraCode[0] == 'u' ? LoongArch::XR0 : LoongArch::VR0));
114 +return false;
115 + }
107 116 // TODO: handle other extra codes if any.
108 117 }
109 118 }
Original file line number Diff line number Diff line change
@@ -12,3 +12,43 @@ entry:
12 12 %0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"()
13 13 ret void
14 14 }
15 +
16 +define void @test_u_2xi64() nounwind {
17 +; CHECK-LABEL: test_u_2xi64:
18 +; CHECK: # %bb.0: # %entry
19 +; CHECK-NEXT: #APP
20 +; CHECK-NEXT: xvldi $xr0, 1
21 +; CHECK-NEXT: #NO_APP
22 +; CHECK-NEXT: ret
23 +entry:
24 +%0 = tail call <2 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"()
25 +ret void
26 +}
27 +
28 +define void @test_w_4xi64() nounwind {
29 +; CHECK-LABEL: test_w_4xi64:
30 +; CHECK: # %bb.0: # %entry
31 +; CHECK-NEXT: #APP
32 +; CHECK-NEXT: vldi $vr0, 1
33 +; CHECK-NEXT: #NO_APP
34 +; CHECK-NEXT: ret
35 +entry:
36 +%0 = tail call <4 x i64> asm sideeffect "vldi ${0:w}, 1", "=f"()
37 +ret void
38 +}
39 +
40 +define void @m128i_to_m256i(ptr %out, ptr %in) nounwind {
41 +; CHECK-LABEL: m128i_to_m256i:
42 +; CHECK: # %bb.0:
43 +; CHECK-NEXT: vld vr0,vr0, vr0,a1, 0
44 +; CHECK-NEXT: xvrepli.b $xr1, 0
45 +; CHECK-NEXT: #APP
46 +; CHECK-NEXT: xvpermi.q xr1,xr1, xr1,xr0, 32
47 +; CHECK-NEXT: #NO_APP
48 +; CHECK-NEXT: xvst xr1,xr1, xr1,a0, 0
49 +; CHECK-NEXT: ret
50 +%v = load <2 x i64>, ptr %in
51 +%x = call <4 x i64> asm sideeffect "xvpermi.q 0:u,{0:u}, 0:u,{1:u}, 32", "=f,f,0"(<2 x i64> %v, <4 x i64> zeroinitializer)
52 +store <4 x i64> %x, ptr %out
53 +ret void
54 +}