Skip to content

Commit f09bcfb

Browse files
SixWeiningtstellar
authored andcommitted
[LoongArch] Relax the restrictions of inlineasm operand modifier 'u' and 'w' (#129864)
- Allow 'u' and 'w' on LASX, LSX or floating point register operands. - Also add missing description in LangRef. Fixes #129863. (cherry picked from commit bae6644)
1 parent f62b50e commit f09bcfb

File tree

3 files changed

+64
-13
lines changed

3 files changed

+64
-13
lines changed

llvm/docs/LangRef.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5826,6 +5826,8 @@ Hexagon:
58265826

58275827
LoongArch:
58285828

5829+
- ``u``: Print an LASX register.
5830+
- ``w``: Print an LSX register.
58295831
- ``z``: Print $zero register if operand is zero, otherwise print it normally.
58305832

58315833
MSP430:

llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,29 @@ bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
9090
return false;
9191
}
9292
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;
10093
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+
}
107116
// TODO: handle other extra codes if any.
108117
}
109118
}

llvm/test/CodeGen/LoongArch/lasx/inline-asm-operand-modifier.ll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,43 @@ entry:
1212
%0 = tail call <4 x i64> asm sideeffect "xvldi ${0:u}, 1", "=f"()
1313
ret void
1414
}
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, $a1, 0
44+
; CHECK-NEXT: xvrepli.b $xr1, 0
45+
; CHECK-NEXT: #APP
46+
; CHECK-NEXT: xvpermi.q $xr1, $xr0, 32
47+
; CHECK-NEXT: #NO_APP
48+
; CHECK-NEXT: xvst $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}, ${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+
}

0 commit comments

Comments
 (0)