Commit 53d05686 by Srdjan Obucina Committed by Jim Stichnoth

Subzero, MIPS32: Intrinsic calls for ABS.fmt and SQRT.fmt

This patch adds ABS.fmt and SQRT.fmt instructions for intrinsic calls. Test cases are copied from nacl-other-intrinsics.ll. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2325703002 . Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
parent b85cde16
......@@ -60,6 +60,8 @@ const char *InstMIPS32::getWidthString(Type Ty) {
return "TBD";
}
template <> const char *InstMIPS32Abs_d::Opcode = "abs.d";
template <> const char *InstMIPS32Abs_s::Opcode = "abs.s";
template <> const char *InstMIPS32Add::Opcode = "add";
template <> const char *InstMIPS32Add_d::Opcode = "add.d";
template <> const char *InstMIPS32Add_s::Opcode = "add.s";
......@@ -104,6 +106,8 @@ template <> const char *InstMIPS32Slt::Opcode = "slt";
template <> const char *InstMIPS32Slti::Opcode = "slti";
template <> const char *InstMIPS32Sltiu::Opcode = "sltiu";
template <> const char *InstMIPS32Sltu::Opcode = "sltu";
template <> const char *InstMIPS32Sqrt_d::Opcode = "sqrt.d";
template <> const char *InstMIPS32Sqrt_s::Opcode = "sqrt.s";
template <> const char *InstMIPS32Sra::Opcode = "sra";
template <> const char *InstMIPS32Srav::Opcode = "srav";
template <> const char *InstMIPS32Srl::Opcode = "srl";
......
......@@ -145,6 +145,8 @@ class InstMIPS32 : public InstTarget {
public:
enum InstKindMIPS32 {
k__Start = Inst::Target,
Abs_d,
Abs_s,
Add,
Add_d,
Add_s,
......@@ -198,6 +200,8 @@ public:
Srav,
Srl,
Srlv,
Sqrt_d,
Sqrt_s,
Sub,
Sub_d,
Sub_s,
......@@ -873,6 +877,8 @@ private:
const uint32_t Imm;
};
using InstMIPS32Abs_d = InstMIPS32TwoAddrFPR<InstMIPS32::Abs_d>;
using InstMIPS32Abs_s = InstMIPS32TwoAddrFPR<InstMIPS32::Abs_s>;
using InstMIPS32Add = InstMIPS32ThreeAddrGPR<InstMIPS32::Add>;
using InstMIPS32Add_d = InstMIPS32ThreeAddrFPR<InstMIPS32::Add_d>;
using InstMIPS32Add_s = InstMIPS32ThreeAddrFPR<InstMIPS32::Add_s>;
......@@ -917,6 +923,8 @@ using InstMIPS32Slt = InstMIPS32ThreeAddrGPR<InstMIPS32::Slt>;
using InstMIPS32Slti = InstMIPS32Imm16<InstMIPS32::Slti>;
using InstMIPS32Sltiu = InstMIPS32Imm16<InstMIPS32::Sltiu>;
using InstMIPS32Sltu = InstMIPS32ThreeAddrGPR<InstMIPS32::Sltu>;
using InstMIPS32Sqrt_d = InstMIPS32TwoAddrFPR<InstMIPS32::Sqrt_d>;
using InstMIPS32Sqrt_s = InstMIPS32TwoAddrFPR<InstMIPS32::Sqrt_s>;
using InstMIPS32Sra = InstMIPS32Imm16<InstMIPS32::Sra>;
using InstMIPS32Srav = InstMIPS32ThreeAddrGPR<InstMIPS32::Srav>;
using InstMIPS32Srl = InstMIPS32Imm16<InstMIPS32::Srl>;
......
......@@ -2548,6 +2548,8 @@ void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) {
}
void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
Variable *Dest = Instr->getDest();
Type DestTy = (Dest == nullptr) ? IceType_void : Dest->getType();
switch (Instr->getIntrinsicInfo().ID) {
case Intrinsics::AtomicCmpxchg: {
UnimplementedLoweringError(this, Instr);
......@@ -2594,7 +2596,15 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return;
}
case Intrinsics::Fabs: {
UnimplementedLoweringError(this, Instr);
if (isScalarFloatingType(DestTy)) {
Variable *T = makeReg(DestTy);
if (DestTy == IceType_f32) {
_abs_s(T, legalizeToReg(Instr->getArg(0)));
} else {
_abs_d(T, legalizeToReg(Instr->getArg(0)));
}
_mov(Dest, T);
}
return;
}
case Intrinsics::Longjmp: {
......@@ -2654,7 +2664,15 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return;
}
case Intrinsics::Sqrt: {
UnimplementedLoweringError(this, Instr);
if (isScalarFloatingType(DestTy)) {
Variable *T = makeReg(DestTy);
if (DestTy == IceType_f32) {
_sqrt_s(T, legalizeToReg(Instr->getArg(0)));
} else {
_sqrt_d(T, legalizeToReg(Instr->getArg(0)));
}
_mov(Dest, T);
}
return;
}
case Intrinsics::Stacksave: {
......
......@@ -187,6 +187,14 @@ public:
Context.insert<InstMIPS32Ret>(RA, Src0);
}
void _abs_d(Variable *Dest, Variable *Src) {
Context.insert<InstMIPS32Abs_d>(Dest, Src);
}
void _abs_s(Variable *Dest, Variable *Src) {
Context.insert<InstMIPS32Abs_s>(Dest, Src);
}
void _add_d(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Add_d>(Dest, Src0, Src1);
}
......@@ -359,6 +367,14 @@ public:
Context.insert<InstMIPS32Sltu>(Dest, Src0, Src1);
}
void _sqrt_d(Variable *Dest, Variable *Src) {
Context.insert<InstMIPS32Sqrt_d>(Dest, Src);
}
void _sqrt_s(Variable *Dest, Variable *Src) {
Context.insert<InstMIPS32Sqrt_s>(Dest, Src);
}
void _sra(Variable *Dest, Variable *Src, uint32_t Imm) {
Context.insert<InstMIPS32Sra>(Dest, Src, Imm);
}
......
; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\
; RUN: -i %s --args -Om1 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %s
; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\
; RUN: -i %s --args -O2 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32-O2 %s
declare float @llvm.sqrt.f32(float)
declare double @llvm.sqrt.f64(double)
declare float @llvm.fabs.f32(float)
declare double @llvm.fabs.f64(double)
define internal float @test_sqrt_float(float %x, i32 %iptr) {
entry:
%r = call float @llvm.sqrt.f32(float %x)
%r2 = call float @llvm.sqrt.f32(float %r)
%r3 = call float @llvm.sqrt.f32(float -0.0)
%r4 = fadd float %r2, %r3
ret float %r4
}
; MIPS32-LABEL: test_sqrt_float
; MIPS32: sqrt.s
; MIPS32: sqrt.s
; MIPS32: sqrt.s
; MIPS32: add.s
; MIPS32-O2-LABEL: test_sqrt_float
; MIPS32-O2: sqrt.s
; MIPS32-O2: sqrt.s
; MIPS32-O2: sqrt.s
; MIPS32-O2: add.s
define internal double @test_sqrt_double(double %x, i32 %iptr) {
entry:
%r = call double @llvm.sqrt.f64(double %x)
%r2 = call double @llvm.sqrt.f64(double %r)
%r3 = call double @llvm.sqrt.f64(double -0.0)
%r4 = fadd double %r2, %r3
ret double %r4
}
; MIPS32-LABEL: test_sqrt_double
; MIPS32: sqrt.d
; MIPS32: sqrt.d
; MIPS32: sqrt.d
; MIPS32: add.d
; MIPS32-O2-LABEL: test_sqrt_double
; MIPS32-O2: sqrt.d
; MIPS32-O2: sqrt.d
; MIPS32-O2: sqrt.d
; MIPS32-O2: add.d
define internal float @test_sqrt_ignored(float %x, double %y) {
entry:
%ignored1 = call float @llvm.sqrt.f32(float %x)
%ignored2 = call double @llvm.sqrt.f64(double %y)
ret float 0.0
}
; MIPS32-LABEL: test_sqrt_ignored
; MIPS32: sqrt.s
; MIPS32: sqrt.d
; MIPS32-O2-LABEL: test_sqrt_ignored
define internal float @test_fabs_float(float %x) {
entry:
%r = call float @llvm.fabs.f32(float %x)
%r2 = call float @llvm.fabs.f32(float %r)
%r3 = call float @llvm.fabs.f32(float -0.0)
%r4 = fadd float %r2, %r3
ret float %r4
}
; MIPS32-LABEL: test_fabs_float
; MIPS32: abs.s
; MIPS32: abs.s
; MIPS32: abs.s
; MIPS32: add.s
; MIPS32-O2-LABEL: test_fabs_float
; MIPS32-O2: abs.s
; MIPS32-O2: abs.s
; MIPS32-O2: abs.s
; MIPS32-O2: add.s
define internal double @test_fabs_double(double %x) {
entry:
%r = call double @llvm.fabs.f64(double %x)
%r2 = call double @llvm.fabs.f64(double %r)
%r3 = call double @llvm.fabs.f64(double -0.0)
%r4 = fadd double %r2, %r3
ret double %r4
}
; MIPS32-LABEL: test_fabs_double
; MIPS32: abs.d
; MIPS32: abs.d
; MIPS32: abs.d
; MIPS32: add.d
; MIPS32-O2-LABEL: test_fabs_double
; MIPS32-O2: abs.d
; MIPS32-O2: abs.d
; MIPS32-O2: abs.d
; MIPS32-O2: add.d
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment