OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 1898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1909 Func->setError("Cast type not supported"); | 1909 Func->setError("Cast type not supported"); |
1910 return; | 1910 return; |
1911 case InstCast::Sext: { | 1911 case InstCast::Sext: { |
1912 // Src0RM is the source operand legalized to physical register or memory, | 1912 // Src0RM is the source operand legalized to physical register or memory, |
1913 // but not immediate, since the relevant x86 native instructions don't | 1913 // but not immediate, since the relevant x86 native instructions don't |
1914 // allow an immediate operand. If the operand is an immediate, we could | 1914 // allow an immediate operand. If the operand is an immediate, we could |
1915 // consider computing the strength-reduced result at translation time, | 1915 // consider computing the strength-reduced result at translation time, |
1916 // but we're unlikely to see something like that in the bitcode that | 1916 // but we're unlikely to see something like that in the bitcode that |
1917 // the optimizer wouldn't have already taken care of. | 1917 // the optimizer wouldn't have already taken care of. |
1918 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 1918 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
1919 if (Dest->getType() == IceType_i64) { | 1919 if (isVectorType(Dest->getType())) { |
1920 // t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2 | |
1921 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | |
1922 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | |
1923 Variable *T_Lo = makeReg(DestLo->getType()); | |
1924 if (Src0RM->getType() == IceType_i32) | |
1925 _mov(T_Lo, Src0RM); | |
1926 else | |
1927 _movsx(T_Lo, Src0RM); | |
1928 _mov(DestLo, T_Lo); | |
1929 Variable *T_Hi = NULL; | |
1930 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31); | |
1931 _mov(T_Hi, T_Lo); | |
1932 _sar(T_Hi, Shift); | |
1933 _mov(DestHi, T_Hi); | |
1934 } else if (isVectorType(Dest->getType())) { | |
1935 Type DestTy = Dest->getType(); | 1920 Type DestTy = Dest->getType(); |
1936 if (DestTy == IceType_v16i8) { | 1921 if (DestTy == IceType_v16i8) { |
1937 // onemask = materialize(1,1,...); dst = (src & onemask) > 0 | 1922 // onemask = materialize(1,1,...); dst = (src & onemask) > 0 |
1938 Variable *OneMask = makeVectorOfOnes(Dest->getType()); | 1923 Variable *OneMask = makeVectorOfOnes(Dest->getType()); |
1939 Variable *T = makeReg(DestTy); | 1924 Variable *T = makeReg(DestTy); |
1940 _movp(T, Src0RM); | 1925 _movp(T, Src0RM); |
1941 _pand(T, OneMask); | 1926 _pand(T, OneMask); |
1942 Variable *Zeros = makeVectorOfZeros(Dest->getType()); | 1927 Variable *Zeros = makeVectorOfZeros(Dest->getType()); |
1943 _pcmpgt(T, Zeros); | 1928 _pcmpgt(T, Zeros); |
1944 _movp(Dest, T); | 1929 _movp(Dest, T); |
1945 } else { | 1930 } else { |
1946 // width = width(elty) - 1; dest = (src << width) >> width | 1931 // width = width(elty) - 1; dest = (src << width) >> width |
1947 SizeT ShiftAmount = | 1932 SizeT ShiftAmount = |
1948 X86_CHAR_BIT * typeWidthInBytes(typeElementType(DestTy)) - 1; | 1933 X86_CHAR_BIT * typeWidthInBytes(typeElementType(DestTy)) - 1; |
1949 Constant *ShiftConstant = Ctx->getConstantInt(IceType_i8, ShiftAmount); | 1934 Constant *ShiftConstant = Ctx->getConstantInt(IceType_i8, ShiftAmount); |
1950 Variable *T = makeReg(DestTy); | 1935 Variable *T = makeReg(DestTy); |
1951 _movp(T, Src0RM); | 1936 _movp(T, Src0RM); |
1952 _psll(T, ShiftConstant); | 1937 _psll(T, ShiftConstant); |
1953 _psra(T, ShiftConstant); | 1938 _psra(T, ShiftConstant); |
1954 _movp(Dest, T); | 1939 _movp(Dest, T); |
1955 } | 1940 } |
| 1941 } else if (Dest->getType() == IceType_i64) { |
| 1942 // t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2 |
| 1943 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31); |
| 1944 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 1945 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| 1946 Variable *T_Lo = makeReg(DestLo->getType()); |
| 1947 if (Src0RM->getType() == IceType_i32) { |
| 1948 _mov(T_Lo, Src0RM); |
| 1949 } else if (Src0RM->getType() == IceType_i1) { |
| 1950 _mov(T_Lo, Src0RM); |
| 1951 _shl(T_Lo, Shift); |
| 1952 _sar(T_Lo, Shift); |
| 1953 } else { |
| 1954 _movsx(T_Lo, Src0RM); |
| 1955 } |
| 1956 _mov(DestLo, T_Lo); |
| 1957 Variable *T_Hi = NULL; |
| 1958 _mov(T_Hi, T_Lo); |
| 1959 _sar(T_Hi, Shift); |
| 1960 _mov(DestHi, T_Hi); |
| 1961 } else if (Src0RM->getType() == IceType_i1) { |
| 1962 // t1 = src |
| 1963 // shl t1, dst_bitwidth - 1 |
| 1964 // sar t1, dst_bitwidth - 1 |
| 1965 // dst = t1 |
| 1966 size_t DestBits = X86_CHAR_BIT * typeWidthInBytes(Dest->getType()); |
| 1967 Constant *ShiftAmount = Ctx->getConstantInt(IceType_i32, DestBits - 1); |
| 1968 Variable *T = NULL; |
| 1969 _mov(T, Src0RM); |
| 1970 _shl(T, ShiftAmount); |
| 1971 _sar(T, ShiftAmount); |
| 1972 _mov(Dest, T); |
1956 } else { | 1973 } else { |
1957 // TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and | |
1958 // also copy to the high operand of a 64-bit variable. | |
1959 // t1 = movsx src; dst = t1 | 1974 // t1 = movsx src; dst = t1 |
1960 Variable *T = makeReg(Dest->getType()); | 1975 Variable *T = makeReg(Dest->getType()); |
1961 _movsx(T, Src0RM); | 1976 _movsx(T, Src0RM); |
1962 _mov(Dest, T); | 1977 _mov(Dest, T); |
1963 } | 1978 } |
1964 break; | 1979 break; |
1965 } | 1980 } |
1966 case InstCast::Zext: { | 1981 case InstCast::Zext: { |
1967 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 1982 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
1968 if (Dest->getType() == IceType_i64) { | 1983 if (isVectorType(Dest->getType())) { |
1969 // t1=movzx src; dst.lo=t1; dst.hi=0 | |
1970 Constant *Zero = Ctx->getConstantZero(IceType_i32); | |
1971 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | |
1972 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | |
1973 Variable *Tmp = makeReg(DestLo->getType()); | |
1974 if (Src0RM->getType() == IceType_i32) | |
1975 _mov(Tmp, Src0RM); | |
1976 else | |
1977 _movzx(Tmp, Src0RM); | |
1978 _mov(DestLo, Tmp); | |
1979 _mov(DestHi, Zero); | |
1980 } else if (Src0RM->getType() == IceType_i1) { | |
1981 // t = Src0RM; t &= 1; Dest = t | |
1982 Operand *One = Ctx->getConstantInt(IceType_i32, 1); | |
1983 Variable *T = makeReg(IceType_i32); | |
1984 _movzx(T, Src0RM); | |
1985 _and(T, One); | |
1986 _mov(Dest, T); | |
1987 } else if (isVectorType(Dest->getType())) { | |
1988 // onemask = materialize(1,1,...); dest = onemask & src | 1984 // onemask = materialize(1,1,...); dest = onemask & src |
1989 Type DestTy = Dest->getType(); | 1985 Type DestTy = Dest->getType(); |
1990 Variable *OneMask = makeVectorOfOnes(DestTy); | 1986 Variable *OneMask = makeVectorOfOnes(DestTy); |
1991 Variable *T = makeReg(DestTy); | 1987 Variable *T = makeReg(DestTy); |
1992 _movp(T, Src0RM); | 1988 _movp(T, Src0RM); |
1993 _pand(T, OneMask); | 1989 _pand(T, OneMask); |
1994 _movp(Dest, T); | 1990 _movp(Dest, T); |
| 1991 } else if (Dest->getType() == IceType_i64) { |
| 1992 // t1=movzx src; dst.lo=t1; dst.hi=0 |
| 1993 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| 1994 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 1995 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| 1996 Variable *Tmp = makeReg(DestLo->getType()); |
| 1997 if (Src0RM->getType() == IceType_i32) { |
| 1998 _mov(Tmp, Src0RM); |
| 1999 } else if (Src0RM->getType() == IceType_i1) { |
| 2000 Constant *One = Ctx->getConstantInt(IceType_i32, 1); |
| 2001 _mov(Tmp, Src0RM); |
| 2002 _and(Tmp, One); |
| 2003 } else { |
| 2004 _movzx(Tmp, Src0RM); |
| 2005 } |
| 2006 _mov(DestLo, Tmp); |
| 2007 _mov(DestHi, Zero); |
| 2008 } else if (Src0RM->getType() == IceType_i1) { |
| 2009 // t = Src0RM; t &= 1; Dest = t |
| 2010 Constant *One = Ctx->getConstantInt(IceType_i32, 1); |
| 2011 Variable *T = makeReg(IceType_i32); |
| 2012 _movzx(T, Src0RM); |
| 2013 _and(T, One); |
| 2014 _mov(Dest, T); |
1995 } else { | 2015 } else { |
1996 // t1 = movzx src; dst = t1 | 2016 // t1 = movzx src; dst = t1 |
1997 Variable *T = makeReg(Dest->getType()); | 2017 Variable *T = makeReg(Dest->getType()); |
1998 _movzx(T, Src0RM); | 2018 _movzx(T, Src0RM); |
1999 _mov(Dest, T); | 2019 _mov(Dest, T); |
2000 } | 2020 } |
2001 break; | 2021 break; |
2002 } | 2022 } |
2003 case InstCast::Trunc: { | 2023 case InstCast::Trunc: { |
2004 if (isVectorType(Dest->getType())) { | 2024 if (isVectorType(Dest->getType())) { |
(...skipping 1908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3913 Operand *Src0 = Inst->getComparison(); | 3933 Operand *Src0 = Inst->getComparison(); |
3914 SizeT NumCases = Inst->getNumCases(); | 3934 SizeT NumCases = Inst->getNumCases(); |
3915 // OK, we'll be slightly less naive by forcing Src into a physical | 3935 // OK, we'll be slightly less naive by forcing Src into a physical |
3916 // register if there are 2 or more uses. | 3936 // register if there are 2 or more uses. |
3917 if (NumCases >= 2) | 3937 if (NumCases >= 2) |
3918 Src0 = legalizeToVar(Src0, true); | 3938 Src0 = legalizeToVar(Src0, true); |
3919 else | 3939 else |
3920 Src0 = legalize(Src0, Legal_Reg | Legal_Mem, true); | 3940 Src0 = legalize(Src0, Legal_Reg | Legal_Mem, true); |
3921 for (SizeT I = 0; I < NumCases; ++I) { | 3941 for (SizeT I = 0; I < NumCases; ++I) { |
3922 // TODO(stichnot): Correct lowering for IceType_i64. | 3942 // TODO(stichnot): Correct lowering for IceType_i64. |
3923 Operand *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I)); | 3943 Constant *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I)); |
3924 _cmp(Src0, Value); | 3944 _cmp(Src0, Value); |
3925 _br(InstX8632Br::Br_e, Inst->getLabel(I)); | 3945 _br(InstX8632Br::Br_e, Inst->getLabel(I)); |
3926 } | 3946 } |
3927 | 3947 |
3928 _br(Inst->getLabelDefault()); | 3948 _br(Inst->getLabelDefault()); |
3929 } | 3949 } |
3930 | 3950 |
3931 void TargetX8632::scalarizeArithmetic(InstArithmetic::OpKind Kind, | 3951 void TargetX8632::scalarizeArithmetic(InstArithmetic::OpKind Kind, |
3932 Variable *Dest, Operand *Src0, | 3952 Variable *Dest, Operand *Src0, |
3933 Operand *Src1) { | 3953 Operand *Src1) { |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4419 Str << "\t.align\t" << Align << "\n"; | 4439 Str << "\t.align\t" << Align << "\n"; |
4420 Str << MangledName << ":\n"; | 4440 Str << MangledName << ":\n"; |
4421 for (SizeT i = 0; i < Size; ++i) { | 4441 for (SizeT i = 0; i < Size; ++i) { |
4422 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4442 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4423 } | 4443 } |
4424 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4444 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4425 } | 4445 } |
4426 } | 4446 } |
4427 | 4447 |
4428 } // end of namespace Ice | 4448 } // end of namespace Ice |
OLD | NEW |