Commit 6fd9c0e3 by Srdjan Obucina Committed by Jim Stichnoth

Subzero, MIPS32: Intrinsic calls Ctlz and Cttz for i64

Implements intrinsic calls llvm.ctlz and llvm.cttz for i64. Also adds test cases for constant operands. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2364093002 . Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
parent 58eeedf7
......@@ -665,7 +665,7 @@ void AssemblerMIPS32::movf(const Operand *OpRd, const Operand *OpRs,
void AssemblerMIPS32::movn(const Operand *OpRd, const Operand *OpRs,
const Operand *OpRt) {
static constexpr IValueT Opcode = 0x44000013;
static constexpr IValueT Opcode = 0x0000000B;
emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "movn");
}
......
......@@ -3069,7 +3069,21 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
break;
}
case IceType_i64: {
UnimplementedLoweringError(this, Instr);
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *SrcHiR = legalizeToReg(hiOperand(Src));
Variable *SrcLoR = legalizeToReg(loOperand(Src));
_clz(T1, SrcHiR);
_clz(T2, SrcLoR);
_addiu(T3, T2, 32);
_movn(T3, T1, SrcHiR);
_addiu(T4, getZero(), 0);
_mov(DestHi, T4);
_mov(DestLo, T3);
break;
}
default:
......@@ -3100,7 +3114,39 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
break;
}
case IceType_i64: {
UnimplementedLoweringError(this, Instr);
auto *THi1 = I32Reg();
auto *THi2 = I32Reg();
auto *THi3 = I32Reg();
auto *THi4 = I32Reg();
auto *THi5 = I32Reg();
auto *THi6 = I32Reg();
auto *TLo1 = I32Reg();
auto *TLo2 = I32Reg();
auto *TLo3 = I32Reg();
auto *TLo4 = I32Reg();
auto *TLo5 = I32Reg();
auto *TLo6 = I32Reg();
auto *TResHi = I32Reg();
auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *SrcHiR = legalizeToReg(hiOperand(Src));
Variable *SrcLoR = legalizeToReg(loOperand(Src));
_addiu(THi1, SrcHiR, -1);
_not(THi2, SrcHiR);
_and(THi3, THi2, THi1);
_clz(THi4, THi3);
_addiu(THi5, getZero(), 64);
_subu(THi6, THi5, THi4);
_addiu(TLo1, SrcLoR, -1);
_not(TLo2, SrcLoR);
_and(TLo3, TLo2, TLo1);
_clz(TLo4, TLo3);
_addiu(TLo5, getZero(), 32);
_subu(TLo6, TLo5, TLo4);
_movn(THi6, TLo6, SrcLoR);
_addiu(TResHi, getZero(), 0);
_mov(DestHi, TResHi);
_mov(DestLo, THi6);
break;
}
default:
......
......@@ -418,6 +418,8 @@ entry:
; CHECK: bsr e{{.*}},{{.*}}e{{.*}}
; ARM32-LABEL: test_ctlz_32_const
; ARM32: clz
; MIPS32-LABEL: test_ctlz_32_const
; MIPS32: clz
define internal i32 @test_ctlz_32_ignored(i32 %x) {
entry:
......@@ -450,6 +452,12 @@ entry:
; ARM32: add {{.*}}, #32
; ARM32: clzne
; ARM32: mov {{.*}}, #0
; MIPS32-LABEL: test_ctlz_64
; MIPS32: clz
; MIPS32: clz
; MIPS32: addiu
; MIPS32: movn
; MIPS32: addiu
define internal i32 @test_ctlz_64_const(i64 %x) {
entry:
......@@ -463,6 +471,12 @@ entry:
; ARM32-LABEL: test_ctlz_64
; ARM32: clz
; ARM32: clzne
; MIPS32-LABEL: test_ctlz_64_const
; MIPS32: clz
; MIPS32: clz
; MIPS32: addiu
; MIPS32: movn
; MIPS32: addiu
define internal i32 @test_ctlz_64_ignored(i64 %x) {
entry:
......@@ -514,6 +528,19 @@ entry:
; ARM32: add {{.*}}, #32
; ARM32: clzne
; ARM32: mov {{.*}}, #0
; MIPS32-LABEL: test_cttz_64
; MIPS32: addiu
; MIPS32: nor
; MIPS32: and
; MIPS32: clz
; MIPS32: li
; MIPS32: subu
; MIPS32: addiu
; MIPS32: nor
; MIPS32: and
; MIPS32: clz
; MIPS32: li
; MIPS32: subu
define internal i32 @test_popcount_32(i32 %x) {
entry:
......
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