Skip to content

Commit eac743d

Browse files
authored
MIPS: Support '%w' token in inline asm template for MSA (llvm#91920)
MSA registers share the FPRs as its bottom half. So that we can use MSA instructions to work with normal float/double: double a, b, c; asm volatile ("fmadd.d %w0, %w1, %w2" : "+f"(a) : "f"(b), "f"(c)); GCC has support it for quite long time.
1 parent 9500a5d commit eac743d

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,15 @@ namespace MipsII {
135135
OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9
136136
};
137137
}
138+
139+
inline static MCRegister getMSARegFromFReg(MCRegister Reg) {
140+
if (Reg >= Mips::F0 && Reg <= Mips::F31)
141+
return Reg - Mips::F0 + Mips::W0;
142+
else if (Reg >= Mips::D0_64 && Reg <= Mips::D31_64)
143+
return Reg - Mips::D0_64 + Mips::W0;
144+
else
145+
return Mips::NoRegister;
146+
}
138147
}
139148

140149
#endif

llvm/lib/Target/Mips/MipsAsmPrinter.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,12 +565,15 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
565565
}
566566
break;
567567
}
568-
case 'w':
569-
// Print MSA registers for the 'f' constraint
570-
// In LLVM, the 'w' modifier doesn't need to do anything.
571-
// We can just call printOperand as normal.
568+
case 'w': {
569+
MCRegister w = getMSARegFromFReg(MO.getReg());
570+
if (w != Mips::NoRegister) {
571+
O << '$' << MipsInstPrinter::getRegisterName(w);
572+
return false;
573+
}
572574
break;
573575
}
576+
}
574577
}
575578

576579
printOperand(MI, OpNum, O);

llvm/test/CodeGen/Mips/msa/inline-asm.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,19 @@ entry:
3232
store <4 x i32> %1, ptr @v4i32_r
3333
ret void
3434
}
35+
36+
define dso_local double @test4(double noundef %a, double noundef %b, double noundef %c) {
37+
entry:
38+
; CHECK-LABEL: test4:
39+
%0 = tail call double asm sideeffect "fmadd.d ${0:w}, ${1:w}, ${2:w}", "=f,f,f,0,~{$1}"(double %b, double %c, double %a)
40+
; CHECK: fmadd.d $w{{([0-9]|[1-3][0-9])}}, $w{{([0-9]|[1-3][0-9])}}, $w{{([0-9]|[1-3][0-9])}}
41+
ret double %0
42+
}
43+
44+
define dso_local float @test5(float noundef %a, float noundef %b, float noundef %c) {
45+
entry:
46+
; CHECK-LABEL: test5:
47+
%0 = tail call float asm sideeffect "fmadd.w ${0:w}, ${1:w}, ${2:w}", "=f,f,f,0,~{$1}"(float %b, float %c, float %a)
48+
; CHECK: fmadd.w $w{{([0-9]|[1-3][0-9])}}, $w{{([0-9]|[1-3][0-9])}}, $w{{([0-9]|[1-3][0-9])}}
49+
ret float %0
50+
}

0 commit comments

Comments
 (0)