Commit d57ed5fa by Srdjan Obucina Committed by Jim Stichnoth

Subzero, MIPS32: lowerSelect for i1, i8, i16, i32, f32, f64

Implements lowerSelect for basic integer and float datatypes. Support for i64 will be added as separate patch. Crucial for running crosstests. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2337023003 . Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
parent bcf2a512
...@@ -104,7 +104,13 @@ template <> const char *InstMIPS32Mflo::Opcode = "mflo"; ...@@ -104,7 +104,13 @@ template <> const char *InstMIPS32Mflo::Opcode = "mflo";
template <> const char *InstMIPS32Mov_d::Opcode = "mov.d"; template <> const char *InstMIPS32Mov_d::Opcode = "mov.d";
template <> const char *InstMIPS32Mov_s::Opcode = "mov.s"; template <> const char *InstMIPS32Mov_s::Opcode = "mov.s";
template <> const char *InstMIPS32Movf::Opcode = "movf"; template <> const char *InstMIPS32Movf::Opcode = "movf";
template <> const char *InstMIPS32Movn::Opcode = "movn";
template <> const char *InstMIPS32Movn_d::Opcode = "movn.d";
template <> const char *InstMIPS32Movn_s::Opcode = "movn.s";
template <> const char *InstMIPS32Movt::Opcode = "movt"; template <> const char *InstMIPS32Movt::Opcode = "movt";
template <> const char *InstMIPS32Movz::Opcode = "movz";
template <> const char *InstMIPS32Movz_d::Opcode = "movz.d";
template <> const char *InstMIPS32Movz_s::Opcode = "movz.s";
template <> const char *InstMIPS32Mtc1::Opcode = "mtc1"; template <> const char *InstMIPS32Mtc1::Opcode = "mtc1";
template <> const char *InstMIPS32Mthi::Opcode = "mthi"; template <> const char *InstMIPS32Mthi::Opcode = "mthi";
template <> const char *InstMIPS32Mtlo::Opcode = "mtlo"; template <> const char *InstMIPS32Mtlo::Opcode = "mtlo";
...@@ -737,7 +743,8 @@ void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const { ...@@ -737,7 +743,8 @@ void InstMIPS32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
const Type SrcType = Src->getType(); const Type SrcType = Src->getType();
// move GP to/from FP // move GP to/from FP
if (DstType != SrcType) { if ((isScalarIntegerType(DstType) && isScalarFloatingType(SrcType)) ||
(isScalarFloatingType(DstType) && isScalarIntegerType(SrcType))) {
if (isScalarFloatingType(DstType)) { if (isScalarFloatingType(DstType)) {
Str << "\t" Str << "\t"
"mtc1" "mtc1"
......
...@@ -228,7 +228,13 @@ public: ...@@ -228,7 +228,13 @@ public:
Mov_d, Mov_d,
Mov_s, Mov_s,
Movf, Movf,
Movn,
Movn_d,
Movn_s,
Movt, Movt,
Movz,
Movz_d,
Movz_s,
Mtc1, Mtc1,
Mthi, Mthi,
Mtlo, Mtlo,
...@@ -1078,7 +1084,13 @@ using InstMIPS32Mflo = InstMIPS32UnaryopGPR<InstMIPS32::Mflo>; ...@@ -1078,7 +1084,13 @@ using InstMIPS32Mflo = InstMIPS32UnaryopGPR<InstMIPS32::Mflo>;
using InstMIPS32Mov_d = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_d>; using InstMIPS32Mov_d = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_d>;
using InstMIPS32Mov_s = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_s>; using InstMIPS32Mov_s = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_s>;
using InstMIPS32Movf = InstMIPS32MovConditional<InstMIPS32::Movf>; using InstMIPS32Movf = InstMIPS32MovConditional<InstMIPS32::Movf>;
using InstMIPS32Movn = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn>;
using InstMIPS32Movn_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_d>;
using InstMIPS32Movn_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_s>;
using InstMIPS32Movt = InstMIPS32MovConditional<InstMIPS32::Movt>; using InstMIPS32Movt = InstMIPS32MovConditional<InstMIPS32::Movt>;
using InstMIPS32Movz = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz>;
using InstMIPS32Movz_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_d>;
using InstMIPS32Movz_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_s>;
using InstMIPS32Mtc1 = InstMIPS32TwoAddrGPR<InstMIPS32::Mtc1>; using InstMIPS32Mtc1 = InstMIPS32TwoAddrGPR<InstMIPS32::Mtc1>;
using InstMIPS32Mthi = InstMIPS32UnaryopGPR<InstMIPS32::Mthi>; using InstMIPS32Mthi = InstMIPS32UnaryopGPR<InstMIPS32::Mthi>;
using InstMIPS32Mtlo = InstMIPS32UnaryopGPR<InstMIPS32::Mtlo>; using InstMIPS32Mtlo = InstMIPS32UnaryopGPR<InstMIPS32::Mtlo>;
......
...@@ -3209,12 +3209,23 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) { ...@@ -3209,12 +3209,23 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) {
if (Instr->hasRetValue()) { if (Instr->hasRetValue()) {
Operand *Src0 = Instr->getRetValue(); Operand *Src0 = Instr->getRetValue();
switch (Src0->getType()) { switch (Src0->getType()) {
case IceType_f32: {
Operand *Src0F = legalizeToReg(Src0);
Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_F0);
_mov(Reg, Src0F);
break;
}
case IceType_f64: {
Operand *Src0F = legalizeToReg(Src0);
Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_F0F1);
_mov(Reg, Src0F);
break;
}
case IceType_i1: case IceType_i1:
case IceType_i8: case IceType_i8:
case IceType_i16: case IceType_i16:
case IceType_i32: { case IceType_i32: {
// Reg = legalizeToReg(Src0, RegMIPS32::Reg_V0); Operand *Src0F = legalizeToReg(Src0);
Operand *Src0F = legalize(Src0, Legal_Reg);
Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0); Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0);
_mov(Reg, Src0F); _mov(Reg, Src0F);
break; break;
...@@ -3235,7 +3246,44 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) { ...@@ -3235,7 +3246,44 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) {
} }
void TargetMIPS32::lowerSelect(const InstSelect *Instr) { void TargetMIPS32::lowerSelect(const InstSelect *Instr) {
UnimplementedLoweringError(this, Instr); Variable *Dest = Instr->getDest();
const Type DestTy = Dest->getType();
if (DestTy == IceType_i64 || isVectorType(DestTy)) {
UnimplementedLoweringError(this, Instr);
return;
}
Variable *DestR = legalizeToReg(Dest);
Variable *SrcTR = legalizeToReg(Instr->getTrueOperand());
Variable *SrcFR = legalizeToReg(Instr->getFalseOperand());
Variable *ConditionR = legalizeToReg(Instr->getCondition());
assert(Instr->getCondition()->getType() == IceType_i1);
switch (DestTy) {
case IceType_i1:
case IceType_i8:
case IceType_i16:
case IceType_i32:
_movn(SrcFR, SrcTR, ConditionR);
_mov(DestR, SrcFR);
_mov(Dest, DestR);
break;
case IceType_f32:
_movn_s(SrcFR, SrcTR, ConditionR);
_mov(DestR, SrcFR);
_mov(Dest, DestR);
break;
case IceType_f64:
_movn_d(SrcFR, SrcTR, ConditionR);
_mov(DestR, SrcFR);
_mov(Dest, DestR);
break;
default:
UnimplementedLoweringError(this, Instr);
}
} }
void TargetMIPS32::lowerShuffleVector(const InstShuffleVector *Instr) { void TargetMIPS32::lowerShuffleVector(const InstShuffleVector *Instr) {
......
...@@ -319,6 +319,18 @@ public: ...@@ -319,6 +319,18 @@ public:
Context.insert<InstMIPS32Lui>(Dest, Src, Reloc); Context.insert<InstMIPS32Lui>(Dest, Src, Reloc);
} }
void _mfc1(Variable *Dest, Variable *Src) {
Context.insert<InstMIPS32Mfc1>(Dest, Src);
}
void _mfhi(Variable *Dest, Operand *Src) {
Context.insert<InstMIPS32Mfhi>(Dest, Src);
}
void _mflo(Variable *Dest, Operand *Src) {
Context.insert<InstMIPS32Mflo>(Dest, Src);
}
void _mov(Variable *Dest, Operand *Src0) { void _mov(Variable *Dest, Operand *Src0) {
assert(Dest != nullptr); assert(Dest != nullptr);
// Variable* Src0_ = llvm::dyn_cast<Variable>(Src0); // Variable* Src0_ = llvm::dyn_cast<Variable>(Src0);
...@@ -347,20 +359,32 @@ public: ...@@ -347,20 +359,32 @@ public:
Context.insert<InstMIPS32Movf>(Src0, Src1, FCC); Context.insert<InstMIPS32Movf>(Src0, Src1, FCC);
} }
void _movn(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Movn>(Dest, Src0, Src1);
}
void _movn_d(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Movn_d>(Dest, Src0, Src1);
}
void _movn_s(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Movn_s>(Dest, Src0, Src1);
}
void _movt(Variable *Src0, Variable *Src1, Operand *FCC) { void _movt(Variable *Src0, Variable *Src1, Operand *FCC) {
Context.insert<InstMIPS32Movt>(Src0, Src1, FCC); Context.insert<InstMIPS32Movt>(Src0, Src1, FCC);
} }
void _mfc1(Variable *Dest, Variable *Src) { void _movz(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Mfc1>(Dest, Src); Context.insert<InstMIPS32Movz>(Dest, Src0, Src1);
} }
void _mfhi(Variable *Dest, Operand *Src) { void _movz_d(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Mfhi>(Dest, Src); Context.insert<InstMIPS32Movz_d>(Dest, Src0, Src1);
} }
void _mflo(Variable *Dest, Operand *Src) { void _movz_s(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Mflo>(Dest, Src); Context.insert<InstMIPS32Movz_s>(Dest, Src0, Src1);
} }
void _mtc1(Variable *Dest, Variable *Src) { void _mtc1(Variable *Dest, Variable *Src) {
......
...@@ -968,6 +968,9 @@ entry: ...@@ -968,6 +968,9 @@ entry:
; ARM32-OM1: vmovne.f32 s{{[0-9]+}} ; ARM32-OM1: vmovne.f32 s{{[0-9]+}}
; ARM32-O2: vmovmi.f32 s{{[0-9]+}} ; ARM32-O2: vmovmi.f32 s{{[0-9]+}}
; ARM32: bx ; ARM32: bx
; MIPS32-LABEL: selectFloatVarVar
; MIPS32: movn.s {{.*}}
; MIPS32: mov.s {{.*}}
define internal double @selectDoubleVarVar(double %a, double %b) { define internal double @selectDoubleVarVar(double %a, double %b) {
entry: entry:
...@@ -985,3 +988,6 @@ entry: ...@@ -985,3 +988,6 @@ entry:
; ARM32-OM1: vmovne.f64 d{{[0-9]+}} ; ARM32-OM1: vmovne.f64 d{{[0-9]+}}
; ARM32-O2: vmovmi.f64 d{{[0-9]+}} ; ARM32-O2: vmovmi.f64 d{{[0-9]+}}
; ARM32: bx ; ARM32: bx
; MIPS32-LABEL: selectDoubleVarVar
; MIPS32: movn.d {{.*}}
; MIPS32: mov.d {{.*}}
...@@ -23,6 +23,20 @@ ...@@ -23,6 +23,20 @@
; RUN: | %if --need=target_ARM32 --need=allow_dump \ ; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OM1 %s ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OM1 %s
; RUN: %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command %p2i --filetype=asm --assemble \
; RUN: --disassemble --target mips32 -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols -skip-unimplemented \
; 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 \
; RUN: --disassemble --target mips32 -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols -skip-unimplemented \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %s
define internal void @testSelect(i32 %a, i32 %b) { define internal void @testSelect(i32 %a, i32 %b) {
entry: entry:
%cmp = icmp slt i32 %a, %b %cmp = icmp slt i32 %a, %b
...@@ -61,6 +75,10 @@ declare void @useInt(i32 %x) ...@@ -61,6 +75,10 @@ declare void @useInt(i32 %x)
; ARM32: bl {{.*}} useInt ; ARM32: bl {{.*}} useInt
; ARM32: bl {{.*}} useInt ; ARM32: bl {{.*}} useInt
; ARM32: bx lr ; ARM32: bx lr
; MIPS32-LABEL: testSelect
; MIPS32: slt {{.*}}
; MIPS32: movn {{.*}}
; MIPS32: move {{.*}}
; Check for valid addressing mode in the cmp instruction when the ; Check for valid addressing mode in the cmp instruction when the
; operand is an immediate. ; operand is an immediate.
...@@ -73,6 +91,9 @@ entry: ...@@ -73,6 +91,9 @@ entry:
; CHECK-NOT: cmp 0x{{[0-9a-f]+}}, ; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
; ARM32-LABEL: testSelectImm32 ; ARM32-LABEL: testSelectImm32
; ARM32-NOT: cmp #{{.*}}, ; ARM32-NOT: cmp #{{.*}},
; MIPS32-LABEL: testSelectImm32
; MIPS32: movn {{.*}}
; MIPS32: move {{.*}}
; Check for valid addressing mode in the cmp instruction when the ; Check for valid addressing mode in the cmp instruction when the
; operand is an immediate. There is a different x86-32 lowering ; operand is an immediate. There is a different x86-32 lowering
...@@ -86,3 +107,4 @@ entry: ...@@ -86,3 +107,4 @@ entry:
; CHECK-NOT: cmp 0x{{[0-9a-f]+}}, ; CHECK-NOT: cmp 0x{{[0-9a-f]+}},
; ARM32-LABEL: testSelectImm64 ; ARM32-LABEL: testSelectImm64
; ARM32-NOT: cmp #{{.*}}, ; ARM32-NOT: cmp #{{.*}},
; MIPS32-LABEL: testSelectImm64
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