Commit 175cb138 by Srdjan Obucina Committed by Jim Stichnoth

Subzero, MIPS32: Intrinsic call Bswap for i16, i32 and i64

Implements intrinsic call llvm.bswap for i16, i32 and i64 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2368343003 . Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
parent 6fd9c0e3
...@@ -1271,6 +1271,7 @@ template <> void InstMIPS32Div::emitIAS(const Cfg *Func) const; ...@@ -1271,6 +1271,7 @@ template <> void InstMIPS32Div::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Div_d::emitIAS(const Cfg *Func) const; template <> void InstMIPS32Div_d::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Div_s::emitIAS(const Cfg *Func) const; template <> void InstMIPS32Div_s::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Lui::emit(const Cfg *Func) const; template <> void InstMIPS32Lui::emit(const Cfg *Func) const;
template <> void InstMIPS32Lui::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Lw::emitIAS(const Cfg *Func) const; template <> void InstMIPS32Lw::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Mfc1::emitIAS(const Cfg *Func) const; template <> void InstMIPS32Mfc1::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Mflo::emit(const Cfg *Func) const; template <> void InstMIPS32Mflo::emit(const Cfg *Func) const;
......
...@@ -3049,7 +3049,96 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -3049,7 +3049,96 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return; return;
} }
case Intrinsics::Bswap: { case Intrinsics::Bswap: {
UnimplementedLoweringError(this, Instr); auto *Src = Instr->getArg(0);
const Type SrcTy = Src->getType();
assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 ||
SrcTy == IceType_i64);
switch (SrcTy) {
case IceType_i16: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *SrcR = legalizeToReg(Src);
_sll(T1, SrcR, 8);
_lui(T2, Ctx->getConstantInt32(255));
_and(T1, T1, T2);
_sll(T3, SrcR, 24);
_or(T1, T3, T1);
_srl(T4, T1, 16);
_mov(Dest, T4);
return;
}
case IceType_i32: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *T5 = I32Reg();
auto *SrcR = legalizeToReg(Src);
_srl(T1, SrcR, 24);
_srl(T2, SrcR, 8);
_andi(T2, T2, 0xFF00);
_or(T1, T2, T1);
_sll(T4, SrcR, 8);
_lui(T3, Ctx->getConstantInt32(255));
_and(T4, T4, T3);
_sll(T5, SrcR, 24);
_or(T4, T5, T4);
_or(T4, T4, T1);
_mov(Dest, T4);
return;
}
case IceType_i64: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *T5 = I32Reg();
auto *T6 = I32Reg();
auto *T7 = I32Reg();
auto *T8 = I32Reg();
auto *T9 = I32Reg();
auto *T10 = I32Reg();
auto *T11 = I32Reg();
auto *T12 = I32Reg();
auto *T13 = I32Reg();
auto *T14 = I32Reg();
auto *T15 = I32Reg();
auto *T16 = I32Reg();
auto *T17 = I32Reg();
auto *T18 = I32Reg();
auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Src = legalizeUndef(Src);
auto *SrcLoR = legalizeToReg(loOperand(Src));
auto *SrcHiR = legalizeToReg(hiOperand(Src));
_sll(T1, SrcHiR, 8);
_srl(T2, SrcHiR, 24);
_srl(T3, SrcHiR, 8);
_andi(T3, T3, 0xFF00);
_lui(T4, Ctx->getConstantInt32(255));
_or(T5, T3, T2);
_and(T6, T1, T4);
_sll(T7, SrcHiR, 24);
_or(T8, T7, T6);
_srl(T9, SrcLoR, 24);
_srl(T10, SrcLoR, 8);
_andi(T11, T10, 0xFF00);
_or(T12, T8, T5);
_or(T13, T11, T9);
_sll(T14, SrcLoR, 8);
_and(T15, T14, T4);
_sll(T16, SrcLoR, 24);
_or(T17, T16, T15);
_or(T18, T17, T13);
_mov(DestLo, T12);
_mov(DestHi, T18);
return;
}
default:
llvm::report_fatal_error("Control flow should never have reached here.");
}
return; return;
} }
case Intrinsics::Ctpop: { case Intrinsics::Ctpop: {
......
...@@ -353,6 +353,14 @@ entry: ...@@ -353,6 +353,14 @@ entry:
; ARM32-LABEL: test_bswap_16 ; ARM32-LABEL: test_bswap_16
; ARM32: rev ; ARM32: rev
; ARM32: lsr {{.*}} #16 ; ARM32: lsr {{.*}} #16
; MIPS32-LABEL: test_bswap_16
; MIPS32: sll {{.*}},0x8
; MIPS32: lui {{.*}},0xff
; MIPS32: and
; MIPS32: sll {{.*}},0x18
; MIPS32: or
; MIPS32: srl {{.*}},0x10
; MIPS32: andi {{.*}},0xffff
define internal i32 @test_bswap_32(i32 %x) { define internal i32 @test_bswap_32(i32 %x) {
entry: entry:
...@@ -363,6 +371,17 @@ entry: ...@@ -363,6 +371,17 @@ entry:
; CHECK: bswap e{{.*}} ; CHECK: bswap e{{.*}}
; ARM32-LABEL: test_bswap_32 ; ARM32-LABEL: test_bswap_32
; ARM32: rev ; ARM32: rev
; MIPS32-LABEL: test_bswap_32
; MIPS32: srl {{.*}},0x18
; MIPS32: srl {{.*}},0x8
; MIPS32: andi {{.*}},0xff00
; MIPS32: or
; MIPS32: sll {{.*}},0x8
; MIPS32: lui {{.*}},0xff
; MIPS32: and
; MIPS32: sll {{.*}},0x18
; MIPS32: or
; MIPS32: or
define internal i64 @test_bswap_64(i64 %x) { define internal i64 @test_bswap_64(i64 %x) {
entry: entry:
...@@ -375,6 +394,26 @@ entry: ...@@ -375,6 +394,26 @@ entry:
; ARM32-LABEL: test_bswap_64 ; ARM32-LABEL: test_bswap_64
; ARM32: rev ; ARM32: rev
; ARM32: rev ; ARM32: rev
; MIPS32-LABEL: test_bswap_64
; MIPS32: sll {{.*}},0x8
; MIPS32: srl {{.*}},0x18
; MIPS32: srl {{.*}},0x8
; MIPS32: andi {{.*}},0xff00
; MIPS32: lui {{.*}},0xff
; MIPS32: or
; MIPS32: and
; MIPS32: sll {{.*}},0x18
; MIPS32: or
; MIPS32: srl {{.*}},0x18
; MIPS32: srl {{.*}},0x8
; MIPS32: andi {{.*}},0xff00
; MIPS32: or
; MIPS32: or
; MIPS32: sll {{.*}},0x8
; MIPS32: and
; MIPS32: sll {{.*}},0x18
; MIPS32: or
; MIPS32: or
define internal i64 @test_bswap_64_undef() { define internal i64 @test_bswap_64_undef() {
entry: entry:
...@@ -387,6 +426,26 @@ entry: ...@@ -387,6 +426,26 @@ entry:
; ARM32-LABEL: test_bswap_64 ; ARM32-LABEL: test_bswap_64
; ARM32: rev ; ARM32: rev
; ARM32: rev ; ARM32: rev
; MIPS32-LABEL: test_bswap_64_undef
; MIPS32: sll {{.*}},0x8
; MIPS32: srl {{.*}},0x18
; MIPS32: srl {{.*}},0x8
; MIPS32: andi {{.*}},0xff00
; MIPS32: lui {{.*}},0xff
; MIPS32: or
; MIPS32: and
; MIPS32: sll {{.*}},0x18
; MIPS32: or
; MIPS32: srl {{.*}},0x18
; MIPS32: srl {{.*}},0x8
; MIPS32: andi {{.*}},0xff00
; MIPS32: or
; MIPS32: or
; MIPS32: sll {{.*}},0x8
; MIPS32: and
; MIPS32: sll {{.*}},0x18
; MIPS32: or
; MIPS32: or
define internal i32 @test_ctlz_32(i32 %x) { define internal i32 @test_ctlz_32(i32 %x) {
entry: 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