Commit 4c49b108 by Srdjan Obucina Committed by Jim Stichnoth

Subzero, MIPS32: Filling missing bits from genTargetHelperCallFor

Implements missing calls to runtime libraries, covering mostly data casting. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2363333002 . Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
parent 623f8ce3
...@@ -992,6 +992,17 @@ template <> void InstMIPS32Movz_s::emitIAS(const Cfg *Func) const { ...@@ -992,6 +992,17 @@ template <> void InstMIPS32Movz_s::emitIAS(const Cfg *Func) const {
Asm->movz_s(getDest(), getSrc(0), getSrc(1)); Asm->movz_s(getDest(), getSrc(0), getSrc(1));
} }
template <> void InstMIPS32Mtc1::emit(const Cfg *Func) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 1);
Str << "\t" << Opcode << "\t";
getSrc(0)->emit(Func);
Str << ", ";
getDest()->emit(Func);
}
template <> void InstMIPS32Mtc1::emitIAS(const Cfg *Func) const { template <> void InstMIPS32Mtc1::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>(); auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Asm->mtc1(getDest(), getSrc(0)); Asm->mtc1(getDest(), getSrc(0));
......
...@@ -1287,6 +1287,7 @@ template <> void InstMIPS32Movt::emitIAS(const Cfg *Func) const; ...@@ -1287,6 +1287,7 @@ template <> void InstMIPS32Movt::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Movz_d::emitIAS(const Cfg *Func) const; template <> void InstMIPS32Movz_d::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Movz_s::emitIAS(const Cfg *Func) const; template <> void InstMIPS32Movz_s::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Mtc1::emit(const Cfg *Func) const; template <> void InstMIPS32Mtc1::emit(const Cfg *Func) const;
template <> void InstMIPS32Mtc1::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Mtlo::emit(const Cfg *Func) const; template <> void InstMIPS32Mtlo::emit(const Cfg *Func) const;
template <> void InstMIPS32Mtlo::emitIAS(const Cfg *Func) const; template <> void InstMIPS32Mtlo::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Mthi::emit(const Cfg *Func) const; template <> void InstMIPS32Mthi::emit(const Cfg *Func) const;
......
...@@ -309,16 +309,26 @@ void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { ...@@ -309,16 +309,26 @@ void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) {
return; return;
case InstCast::Fptosi: case InstCast::Fptosi:
case InstCast::Fptoui: { case InstCast::Fptoui: {
if (DestTy != IceType_i64) { if ((DestTy != IceType_i32) && (DestTy != IceType_i64)) {
return; return;
} }
const bool DestIs32 = DestTy == IceType_i32;
const bool DestIsSigned = CastKind == InstCast::Fptosi; const bool DestIsSigned = CastKind == InstCast::Fptosi;
const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy); const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy);
Operand *TargetHelper = Ctx->getRuntimeHelperFunc( RuntimeHelper RTHFunc = RuntimeHelper::H_Num;
Src0IsF32 ? (DestIsSigned ? RuntimeHelper::H_fptosi_f32_i64 if (DestIsSigned) {
: RuntimeHelper::H_fptoui_f32_i64) if (DestIs32) {
: (DestIsSigned ? RuntimeHelper::H_fptosi_f64_i64 return;
: RuntimeHelper::H_fptoui_f64_i64)); }
RTHFunc = Src0IsF32 ? RuntimeHelper::H_fptosi_f32_i64
: RuntimeHelper::H_fptosi_f64_i64;
} else {
RTHFunc = Src0IsF32 ? (DestIs32 ? RuntimeHelper::H_fptoui_f32_i32
: RuntimeHelper::H_fptoui_f32_i64)
: (DestIs32 ? RuntimeHelper::H_fptoui_f64_i32
: RuntimeHelper::H_fptoui_f64_i64);
}
Operand *TargetHelper = Ctx->getRuntimeHelperFunc(RTHFunc);
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
...@@ -328,16 +338,26 @@ void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { ...@@ -328,16 +338,26 @@ void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) {
} }
case InstCast::Sitofp: case InstCast::Sitofp:
case InstCast::Uitofp: { case InstCast::Uitofp: {
if (SrcTy != IceType_i64) { if ((SrcTy != IceType_i32) && (SrcTy != IceType_i64)) {
return; return;
} }
const bool SourceIs32 = SrcTy == IceType_i32;
const bool SourceIsSigned = CastKind == InstCast::Sitofp; const bool SourceIsSigned = CastKind == InstCast::Sitofp;
const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType());
Operand *TargetHelper = Ctx->getRuntimeHelperFunc( RuntimeHelper RTHFunc = RuntimeHelper::H_Num;
DestIsF32 ? (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f32 if (SourceIsSigned) {
: RuntimeHelper::H_uitofp_i64_f32) if (SourceIs32) {
: (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f64 return;
: RuntimeHelper::H_uitofp_i64_f64)); }
RTHFunc = DestIsF32 ? RuntimeHelper::H_sitofp_i64_f32
: RuntimeHelper::H_sitofp_i64_f64;
} else {
RTHFunc = DestIsF32 ? (SourceIs32 ? RuntimeHelper::H_uitofp_i32_f32
: RuntimeHelper::H_uitofp_i64_f32)
: (SourceIs32 ? RuntimeHelper::H_uitofp_i32_f64
: RuntimeHelper::H_uitofp_i64_f64);
}
Operand *TargetHelper = Ctx->getRuntimeHelperFunc(RTHFunc);
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
...@@ -2584,54 +2604,67 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { ...@@ -2584,54 +2604,67 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
_mov(Dest, DestR); _mov(Dest, DestR);
break; break;
} }
case InstCast::Fptosi: { case InstCast::Fptosi:
case InstCast::Fptoui: {
if (llvm::isa<Variable64On32>(Dest)) { if (llvm::isa<Variable64On32>(Dest)) {
llvm::report_fatal_error("fp-to-i64 should have been prelowered."); llvm::report_fatal_error("fp-to-i64 should have been prelowered.");
return; return;
} }
if (Src0Ty == IceType_f32 && DestTy == IceType_i32) { if (DestTy != IceType_i64) {
Variable *Src0R = legalizeToReg(Src0); if (Src0Ty == IceType_f32 && isScalarIntegerType(DestTy)) {
Variable *FTmp = makeReg(IceType_f32); Variable *Src0R = legalizeToReg(Src0);
_trunc_w_s(FTmp, Src0R); Variable *FTmp = makeReg(IceType_f32);
_mov(Dest, FTmp); _trunc_w_s(FTmp, Src0R);
} else { _mov(Dest, FTmp);
UnimplementedLoweringError(this, Instr); return;
} }
break; if (Src0Ty == IceType_f64 && isScalarIntegerType(DestTy)) {
} Variable *Src0R = legalizeToReg(Src0);
case InstCast::Fptoui: Variable *FTmp = makeReg(IceType_f64);
if (llvm::isa<Variable64On32>(Dest)) { _trunc_w_d(FTmp, Src0R);
llvm::report_fatal_error("fp-to-i64 should have been prelowered."); _mov(Dest, FTmp);
return; return;
}
} }
UnimplementedLoweringError(this, Instr); UnimplementedLoweringError(this, Instr);
break; break;
case InstCast::Sitofp: {
if (llvm::isa<Variable64On32>(Dest)) {
llvm::report_fatal_error("i64-to-fp should have been prelowered.");
return;
}
if (Src0Ty == IceType_i32 && DestTy == IceType_f32) {
Variable *Src0R = legalizeToReg(Src0);
Variable *FTmp1 = makeReg(IceType_f32);
Variable *FTmp2 = makeReg(IceType_f32);
_mov(FTmp1, Src0R);
_cvt_s_w(FTmp2, FTmp1);
_mov(Dest, FTmp2);
} else {
UnimplementedLoweringError(this, Instr);
}
break;
} }
case InstCast::Sitofp:
case InstCast::Uitofp: { case InstCast::Uitofp: {
if (llvm::isa<Variable64On32>(Dest)) { if (llvm::isa<Variable64On32>(Dest)) {
llvm::report_fatal_error("i64-to-fp should have been prelowered."); llvm::report_fatal_error("i64-to-fp should have been prelowered.");
return; return;
} }
if (Src0Ty != IceType_i64) {
if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) {
Variable *Src0R = legalizeToReg(Src0);
Variable *FTmp1 = makeReg(IceType_f32);
Variable *FTmp2 = makeReg(IceType_f32);
_mtc1(FTmp1, Src0R);
_cvt_s_w(FTmp2, FTmp1);
_mov(Dest, FTmp2);
return;
}
if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) {
Variable *Src0R = legalizeToReg(Src0);
Variable *FTmp1 = makeReg(IceType_f64);
Variable *FTmp2 = makeReg(IceType_f64);
_mtc1(FTmp1, Src0R);
_cvt_d_w(FTmp2, FTmp1);
_mov(Dest, FTmp2);
return;
}
}
UnimplementedLoweringError(this, Instr); UnimplementedLoweringError(this, Instr);
break; break;
} }
case InstCast::Bitcast: { case InstCast::Bitcast: {
Operand *Src0 = Instr->getSrc(0);
if (DestTy == Src0->getType()) {
auto *Assign = InstAssign::create(Func, Dest, Src0);
lowerAssign(Assign);
return;
}
switch (DestTy) { switch (DestTy) {
case IceType_NUM: case IceType_NUM:
case IceType_void: case IceType_void:
......
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