Commit e160ed92 by Sagar Thakur Committed by Jim Stichnoth

[Subzero][MIPS32] Implement i1 cast operations

R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2017043002 . Patch from Sagar Thakur <sagar.thakur@imgtec.com>.
parent 2f593bbb
...@@ -112,7 +112,7 @@ public: ...@@ -112,7 +112,7 @@ public:
assert(Index < NumSrcs); assert(Index < NumSrcs);
assert(!isDeleted()); assert(!isDeleted());
assert(LiveRangesEnded == 0); assert(LiveRangesEnded == 0);
//Invalidates liveness info because the use Srcs[Index] is removed. // Invalidates liveness info because the use Srcs[Index] is removed.
Srcs[Index] = Replacement; Srcs[Index] = Replacement;
} }
......
...@@ -211,9 +211,7 @@ public: ...@@ -211,9 +211,7 @@ public:
return Operand->getKind() == K; return Operand->getKind() == K;
} }
SizeT hashValue() const override { SizeT hashValue() const override { return std::hash<PrimType>()(Value); }
return std::hash<PrimType>()(Value);
}
virtual bool shouldBeRandomizedOrPooled() const override { return false; } virtual bool shouldBeRandomizedOrPooled() const override { return false; }
...@@ -780,9 +778,7 @@ public: ...@@ -780,9 +778,7 @@ public:
return Kind >= kVariable && Kind <= kVariable_Max; return Kind >= kVariable && Kind <= kVariable_Max;
} }
SizeT hashValue() const override { SizeT hashValue() const override { return std::hash<SizeT>()(getIndex()); }
return std::hash<SizeT>()(getIndex());
}
protected: protected:
Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index)
......
...@@ -1009,10 +1009,15 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { ...@@ -1009,10 +1009,15 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
const Type DestTy = Dest->getType(); const Type DestTy = Dest->getType();
const Type Src0Ty = Src0->getType(); const Type Src0Ty = Src0->getType();
const uint32_t ShiftAmount = const uint32_t ShiftAmount =
INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty)); (Src0Ty == IceType_i1
const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1; ? INT32_BITS - 1
: INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty)));
if (isVectorType(DestTy) || Src0->getType() == IceType_i1) { const uint32_t Mask =
(Src0Ty == IceType_i1
? 1
: (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1);
if (isVectorType(DestTy)) {
UnimplementedLoweringError(this, Instr); UnimplementedLoweringError(this, Instr);
return; return;
} }
...@@ -1025,20 +1030,35 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { ...@@ -1025,20 +1030,35 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *Src0R = legalizeToReg(Src0); Variable *Src0R = legalizeToReg(Src0);
Variable *T_Lo = I32Reg(); Variable *T1_Lo = I32Reg();
if (Src0Ty == IceType_i32) { Variable *T2_Lo = I32Reg();
_mov(DestLo, Src0R); Variable *T_Hi = I32Reg();
if (Src0Ty == IceType_i1) {
_sll(T1_Lo, Src0R, INT32_BITS - 1);
_sra(T2_Lo, T1_Lo, INT32_BITS - 1);
_mov(DestHi, T2_Lo);
_mov(DestLo, T2_Lo);
} else if (Src0Ty == IceType_i8 || Src0Ty == IceType_i16) { } else if (Src0Ty == IceType_i8 || Src0Ty == IceType_i16) {
_sll(T_Lo, Src0R, ShiftAmount); _sll(T1_Lo, Src0R, ShiftAmount);
_sra(DestLo, T_Lo, ShiftAmount); _sra(T2_Lo, T1_Lo, ShiftAmount);
_sra(T_Hi, T2_Lo, INT32_BITS - 1);
_mov(DestHi, T_Hi);
_mov(DestLo, T2_Lo);
} else if (Src0Ty == IceType_i32) {
_mov(T1_Lo, Src0R);
_sra(T_Hi, T1_Lo, INT32_BITS - 1);
_mov(DestHi, T_Hi);
_mov(DestLo, T1_Lo);
} }
_sra(DestHi, DestLo, INT32_BITS - 1);
} else { } else {
Variable *Src0R = legalizeToReg(Src0); Variable *Src0R = legalizeToReg(Src0);
Variable *T = makeReg(DestTy); Variable *T1 = makeReg(DestTy);
if (Src0Ty == IceType_i8 || Src0Ty == IceType_i16) { Variable *T2 = makeReg(DestTy);
_sll(T, Src0R, ShiftAmount); if (Src0Ty == IceType_i1 || Src0Ty == IceType_i8 ||
_sra(Dest, T, ShiftAmount); Src0Ty == IceType_i16) {
_sll(T1, Src0R, ShiftAmount);
_sra(T2, T1, ShiftAmount);
_mov(Dest, T2);
} }
} }
break; break;
...@@ -1048,26 +1068,28 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { ...@@ -1048,26 +1068,28 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *Src0R = legalizeToReg(Src0); Variable *Src0R = legalizeToReg(Src0);
Variable *T_Lo = I32Reg();
Variable *T_Hi = I32Reg();
switch (Src0Ty) { if (Src0Ty == IceType_i1 || Src0Ty == IceType_i8 || Src0Ty == IceType_i16)
default: { assert(Src0Ty != IceType_i64); } break; _andi(T_Lo, Src0R, Mask);
case IceType_i32: else if (Src0Ty == IceType_i32)
_mov(DestLo, Src0R); _mov(T_Lo, Src0R);
break; else
case IceType_i8: assert(Src0Ty != IceType_i64);
case IceType_i16: _mov(DestLo, T_Lo);
_andi(DestLo, Src0R, Mask);
break;
}
auto *Zero = getZero(); auto *Zero = getZero();
_addiu(DestHi, Zero, 0); _addiu(T_Hi, Zero, 0);
_mov(DestHi, T_Hi);
} else { } else {
Variable *Src0R = legalizeToReg(Src0); Variable *Src0R = legalizeToReg(Src0);
Variable *T = makeReg(DestTy); Variable *T = makeReg(DestTy);
if (Src0Ty == IceType_i8 || Src0Ty == IceType_i16) if (Src0Ty == IceType_i1 || Src0Ty == IceType_i8 ||
Src0Ty == IceType_i16) {
_andi(T, Src0R, Mask); _andi(T, Src0R, Mask);
_mov(Dest, T); _mov(Dest, T);
}
} }
break; break;
} }
......
...@@ -970,6 +970,10 @@ entry: ...@@ -970,6 +970,10 @@ entry:
; ARM32-OM1: and r0, r0, #1 ; ARM32-OM1: and r0, r0, #1
; ARM32-O2: and r0, r0, #1 ; ARM32-O2: and r0, r0, #1
; MIPS32-LABEL: trunc64To1
; MIPS32: andi {{.*}},a0,0x1
; MIPS32: move v0,{{.*}}
define internal i64 @sext32To64(i32 %a) { define internal i64 @sext32To64(i32 %a) {
entry: entry:
%conv = sext i32 %a to i64 %conv = sext i32 %a to i64
...@@ -987,8 +991,9 @@ entry: ...@@ -987,8 +991,9 @@ entry:
; ARM32: asr {{.*}}, #31 ; ARM32: asr {{.*}}, #31
; MIPS32-LABEL: sext32To64 ; MIPS32-LABEL: sext32To64
; MIPS32-LABEL: sra v1,a0,0x1f ; MIPS32-LABEL: sra {{.*}},a0,0x1f
; MIPS32-LABEL: move v0,a0 ; MIPS32-LABEL: move v1,{{.*}}
; MIPS32-LABEL: move v0,{{.*}}
define internal i64 @sext16To64(i32 %a) { define internal i64 @sext16To64(i32 %a) {
entry: entry:
...@@ -1009,10 +1014,11 @@ entry: ...@@ -1009,10 +1014,11 @@ entry:
; ARM32: asr {{.*}}, #31 ; ARM32: asr {{.*}}, #31
; MIPS32-LABEL: sext16To64 ; MIPS32-LABEL: sext16To64
; MIPS32: sll a0,a0,0x10 ; MIPS32: sll {{.*}},{{.*}},0x10
; MIPS32: sra a0,a0,0x10 ; MIPS32: sra {{.*}},{{.*}},0x10
; MIPS32: sra v1,a0,0x1f ; MIPS32: sra {{.*}},{{.*}},0x1f
; MIPS32: move v0,a0 ; MIPS32: move v1,{{.*}}
; MIPS32: move v0,{{.*}}
define internal i64 @sext8To64(i32 %a) { define internal i64 @sext8To64(i32 %a) {
entry: entry:
...@@ -1033,10 +1039,11 @@ entry: ...@@ -1033,10 +1039,11 @@ entry:
; ARM32: asr {{.*}}, #31 ; ARM32: asr {{.*}}, #31
; MIPS32-LABEL: sext8To64 ; MIPS32-LABEL: sext8To64
; MIPS32: sll a0,a0,0x18 ; MIPS32: sll {{.*}},a0,0x18
; MIPS32: sra a0,a0,0x18 ; MIPS32: sra {{.*}},{{.*}},0x18
; MIPS32: sra v1,a0,0x1f ; MIPS32: sra {{.*}},{{.*}},0x1f
; MIPS32: move v0,a0 ; MIPS32: move v1,{{.*}}
; MIPS32: move v0,{{.*}}
define internal i64 @sext1To64(i32 %a) { define internal i64 @sext1To64(i32 %a) {
entry: entry:
...@@ -1060,6 +1067,12 @@ entry: ...@@ -1060,6 +1067,12 @@ entry:
; ARM32: mvn {{.*}}, #0 ; ARM32: mvn {{.*}}, #0
; ARM32: movne ; ARM32: movne
; MIPS32-LABEL: sext1To64
; MIPS32: sll {{.*}},a0,0x1f
; MIPS32: sra {{.*}},{{.*}},0x1f
; MIPS32: move v1,{{.*}}
; MIPS32: move v0,{{.*}}
define internal i64 @zext32To64(i32 %a) { define internal i64 @zext32To64(i32 %a) {
entry: entry:
%conv = zext i32 %a to i64 %conv = zext i32 %a to i64
...@@ -1077,8 +1090,9 @@ entry: ...@@ -1077,8 +1090,9 @@ entry:
; ARM32: mov {{.*}}, #0 ; ARM32: mov {{.*}}, #0
; MIPS32-LABEL: zext32To64 ; MIPS32-LABEL: zext32To64
; MIPS32: li v1,0 ; MIPS32: li {{.*}},0
; MIPS32: move v0,a0 ; MIPS32: move v1,{{.*}}
; MIPS32: move v0,{{.*}}
define internal i64 @zext16To64(i32 %a) { define internal i64 @zext16To64(i32 %a) {
entry: entry:
...@@ -1099,9 +1113,10 @@ entry: ...@@ -1099,9 +1113,10 @@ entry:
; ARM32: mov {{.*}}, #0 ; ARM32: mov {{.*}}, #0
; MIPS32-LABEL: zext16To64 ; MIPS32-LABEL: zext16To64
; MIPS32: andi a0,a0,0xffff ; MIPS32: andi {{.*}},a0,0xffff
; MIPS32: li v1,0 ; MIPS32: li {{.*}},0
; MIPS32: move v0,a0 ; MIPS32: move v1,{{.*}}
; MIPS32: move v0,{{.*}}
define internal i64 @zext8To64(i32 %a) { define internal i64 @zext8To64(i32 %a) {
entry: entry:
...@@ -1122,9 +1137,10 @@ entry: ...@@ -1122,9 +1137,10 @@ entry:
; ARM32: mov {{.*}}, #0 ; ARM32: mov {{.*}}, #0
; MIPS32-LABEL: zext8To64 ; MIPS32-LABEL: zext8To64
; MIPS32: andi a0,a0,0xff ; MIPS32: andi {{.*}},a0,0xff
; MIPS32: li v1,0 ; MIPS32: li {{.*}},0
; MIPS32: move v0,a0 ; MIPS32: move v1,{{.*}}
; MIPS32: move v0,{{.*}}
define internal i64 @zext1To64(i32 %a) { define internal i64 @zext1To64(i32 %a) {
entry: entry:
...@@ -1145,6 +1161,12 @@ entry: ...@@ -1145,6 +1161,12 @@ entry:
; ARM32: mov {{.*}}, #0 ; ARM32: mov {{.*}}, #0
; ARM32: bx ; ARM32: bx
; MIPS32-LABEL: zext1To64
; MIPS32: andi {{.*}},a0,0x1
; MIPS32: li {{.*}},0
; MIPS32: move v1,{{.*}}
; MIPS32: move v0,{{.*}}
define internal void @icmpEq64(i64 %a, i64 %b, i64 %c, i64 %d) { define internal void @icmpEq64(i64 %a, i64 %b, i64 %c, i64 %d) {
entry: entry:
%cmp = icmp eq i64 %a, %b %cmp = icmp eq i64 %a, %b
......
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