Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1233903002: Factor out legalization of undef, and handle more cases for ARM. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: stuff Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringX86Base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 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 /// \file 10 /// \file
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 if (Var->getIsArg()) { 856 if (Var->getIsArg()) {
857 Lo->setIsArg(); 857 Lo->setIsArg();
858 Hi->setIsArg(); 858 Hi->setIsArg();
859 } 859 }
860 } 860 }
861 861
862 Operand *TargetARM32::loOperand(Operand *Operand) { 862 Operand *TargetARM32::loOperand(Operand *Operand) {
863 assert(Operand->getType() == IceType_i64); 863 assert(Operand->getType() == IceType_i64);
864 if (Operand->getType() != IceType_i64) 864 if (Operand->getType() != IceType_i64)
865 return Operand; 865 return Operand;
866 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 866 if (auto *Var = llvm::dyn_cast<Variable>(Operand)) {
867 split64(Var); 867 split64(Var);
868 return Var->getLo(); 868 return Var->getLo();
869 } 869 }
870 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 870 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
871 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); 871 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue()));
872 } 872 }
873 if (OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) { 873 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) {
874 // Conservatively disallow memory operands with side-effects (pre/post 874 // Conservatively disallow memory operands with side-effects (pre/post
875 // increment) in case of duplication. 875 // increment) in case of duplication.
876 assert(Mem->getAddrMode() == OperandARM32Mem::Offset || 876 assert(Mem->getAddrMode() == OperandARM32Mem::Offset ||
877 Mem->getAddrMode() == OperandARM32Mem::NegOffset); 877 Mem->getAddrMode() == OperandARM32Mem::NegOffset);
878 if (Mem->isRegReg()) { 878 if (Mem->isRegReg()) {
879 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(), 879 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(),
880 Mem->getIndex(), Mem->getShiftOp(), 880 Mem->getIndex(), Mem->getShiftOp(),
881 Mem->getShiftAmt(), Mem->getAddrMode()); 881 Mem->getShiftAmt(), Mem->getAddrMode());
882 } else { 882 } else {
883 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(), 883 return OperandARM32Mem::create(Func, IceType_i32, Mem->getBase(),
884 Mem->getOffset(), Mem->getAddrMode()); 884 Mem->getOffset(), Mem->getAddrMode());
885 } 885 }
886 } 886 }
887 llvm_unreachable("Unsupported operand type"); 887 llvm_unreachable("Unsupported operand type");
888 return nullptr; 888 return nullptr;
889 } 889 }
890 890
891 Operand *TargetARM32::hiOperand(Operand *Operand) { 891 Operand *TargetARM32::hiOperand(Operand *Operand) {
892 assert(Operand->getType() == IceType_i64); 892 assert(Operand->getType() == IceType_i64);
893 if (Operand->getType() != IceType_i64) 893 if (Operand->getType() != IceType_i64)
894 return Operand; 894 return Operand;
895 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 895 if (auto *Var = llvm::dyn_cast<Variable>(Operand)) {
896 split64(Var); 896 split64(Var);
897 return Var->getHi(); 897 return Var->getHi();
898 } 898 }
899 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 899 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
900 return Ctx->getConstantInt32( 900 return Ctx->getConstantInt32(
901 static_cast<uint32_t>(Const->getValue() >> 32)); 901 static_cast<uint32_t>(Const->getValue() >> 32));
902 } 902 }
903 if (OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) { 903 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand)) {
904 // Conservatively disallow memory operands with side-effects 904 // Conservatively disallow memory operands with side-effects
905 // in case of duplication. 905 // in case of duplication.
906 assert(Mem->getAddrMode() == OperandARM32Mem::Offset || 906 assert(Mem->getAddrMode() == OperandARM32Mem::Offset ||
907 Mem->getAddrMode() == OperandARM32Mem::NegOffset); 907 Mem->getAddrMode() == OperandARM32Mem::NegOffset);
908 const Type SplitType = IceType_i32; 908 const Type SplitType = IceType_i32;
909 if (Mem->isRegReg()) { 909 if (Mem->isRegReg()) {
910 // We have to make a temp variable T, and add 4 to either Base or Index. 910 // We have to make a temp variable T, and add 4 to either Base or Index.
911 // The Index may be shifted, so adding 4 can mean something else. 911 // The Index may be shifted, so adding 4 can mean something else.
912 // Thus, prefer T := Base + 4, and use T as the new Base. 912 // Thus, prefer T := Base + 4, and use T as the new Base.
913 Variable *Base = Mem->getBase(); 913 Variable *Base = Mem->getBase();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 Operand *TotalSize = Inst->getSizeInBytes(); 1005 Operand *TotalSize = Inst->getSizeInBytes();
1006 if (const auto *ConstantTotalSize = 1006 if (const auto *ConstantTotalSize =
1007 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { 1007 llvm::dyn_cast<ConstantInteger32>(TotalSize)) {
1008 uint32_t Value = ConstantTotalSize->getValue(); 1008 uint32_t Value = ConstantTotalSize->getValue();
1009 Value = Utils::applyAlignment(Value, Alignment); 1009 Value = Utils::applyAlignment(Value, Alignment);
1010 Operand *SubAmount = legalize(Ctx->getConstantInt32(Value)); 1010 Operand *SubAmount = legalize(Ctx->getConstantInt32(Value));
1011 _sub(SP, SP, SubAmount); 1011 _sub(SP, SP, SubAmount);
1012 } else { 1012 } else {
1013 // Non-constant sizes need to be adjusted to the next highest 1013 // Non-constant sizes need to be adjusted to the next highest
1014 // multiple of the required alignment at runtime. 1014 // multiple of the required alignment at runtime.
1015 TotalSize = legalize(TotalSize); 1015 TotalSize = legalize(TotalSize, Legal_Reg | Legal_Flex);
1016 Variable *T = makeReg(IceType_i32); 1016 Variable *T = makeReg(IceType_i32);
1017 _mov(T, TotalSize); 1017 _mov(T, TotalSize);
1018 Operand *AddAmount = legalize(Ctx->getConstantInt32(Alignment - 1)); 1018 Operand *AddAmount = legalize(Ctx->getConstantInt32(Alignment - 1));
1019 _add(T, T, AddAmount); 1019 _add(T, T, AddAmount);
1020 alignRegisterPow2(T, Alignment); 1020 alignRegisterPow2(T, Alignment);
1021 _sub(SP, SP, T); 1021 _sub(SP, SP, T);
1022 } 1022 }
1023 _mov(Dest, SP); 1023 _mov(Dest, SP);
1024 } 1024 }
1025 1025
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 1094
1095 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) { 1095 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) {
1096 Variable *Dest = Inst->getDest(); 1096 Variable *Dest = Inst->getDest();
1097 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier 1097 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier
1098 // to legalize Src0 to flex or Src1 to flex and there is a reversible 1098 // to legalize Src0 to flex or Src1 to flex and there is a reversible
1099 // instruction. E.g., reverse subtract with immediate, register vs 1099 // instruction. E.g., reverse subtract with immediate, register vs
1100 // register, immediate. 1100 // register, immediate.
1101 // Or it may be the case that the operands aren't swapped, but the 1101 // Or it may be the case that the operands aren't swapped, but the
1102 // bits can be flipped and a different operation applied. 1102 // bits can be flipped and a different operation applied.
1103 // E.g., use BIC (bit clear) instead of AND for some masks. 1103 // E.g., use BIC (bit clear) instead of AND for some masks.
1104 Operand *Src0 = Inst->getSrc(0); 1104 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
1105 Operand *Src1 = Inst->getSrc(1); 1105 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
1106 if (Dest->getType() == IceType_i64) { 1106 if (Dest->getType() == IceType_i64) {
1107 // These helper-call-involved instructions are lowered in this 1107 // These helper-call-involved instructions are lowered in this
1108 // separate switch. This is because we would otherwise assume that 1108 // separate switch. This is because we would otherwise assume that
1109 // we need to legalize Src0 to Src0RLo and Src0Hi. However, those go unused 1109 // we need to legalize Src0 to Src0RLo and Src0Hi. However, those go unused
1110 // with helper calls, and such unused/redundant instructions will fail 1110 // with helper calls, and such unused/redundant instructions will fail
1111 // liveness analysis under -Om1 setting. 1111 // liveness analysis under -Om1 setting.
1112 switch (Inst->getOp()) { 1112 switch (Inst->getOp()) {
1113 default: 1113 default:
1114 break; 1114 break;
1115 case InstArithmetic::Udiv: 1115 case InstArithmetic::Udiv:
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 UnimplementedError(Func->getContext()->getFlags()); 1451 UnimplementedError(Func->getContext()->getFlags());
1452 return; 1452 return;
1453 } 1453 }
1454 } 1454 }
1455 1455
1456 void TargetARM32::lowerAssign(const InstAssign *Inst) { 1456 void TargetARM32::lowerAssign(const InstAssign *Inst) {
1457 Variable *Dest = Inst->getDest(); 1457 Variable *Dest = Inst->getDest();
1458 Operand *Src0 = Inst->getSrc(0); 1458 Operand *Src0 = Inst->getSrc(0);
1459 assert(Dest->getType() == Src0->getType()); 1459 assert(Dest->getType() == Src0->getType());
1460 if (Dest->getType() == IceType_i64) { 1460 if (Dest->getType() == IceType_i64) {
1461 Src0 = legalize(Src0); 1461 Src0 = legalizeUndef(Src0);
1462 Operand *Src0Lo = loOperand(Src0); 1462 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg | Legal_Flex);
1463 Operand *Src0Hi = hiOperand(Src0); 1463 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg | Legal_Flex);
1464 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1464 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
1465 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1465 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1466 Variable *T_Lo = nullptr, *T_Hi = nullptr; 1466 Variable *T_Lo = nullptr, *T_Hi = nullptr;
1467 _mov(T_Lo, Src0Lo); 1467 _mov(T_Lo, Src0Lo);
1468 _mov(DestLo, T_Lo); 1468 _mov(DestLo, T_Lo);
1469 _mov(T_Hi, Src0Hi); 1469 _mov(T_Hi, Src0Hi);
1470 _mov(DestHi, T_Hi); 1470 _mov(DestHi, T_Hi);
1471 } else { 1471 } else {
1472 Operand *SrcR; 1472 Operand *SrcR;
1473 if (Dest->hasReg()) { 1473 if (Dest->hasReg()) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 // Pair of Arg Operand -> GPR number assignments. 1516 // Pair of Arg Operand -> GPR number assignments.
1517 llvm::SmallVector<std::pair<Operand *, int32_t>, 1517 llvm::SmallVector<std::pair<Operand *, int32_t>,
1518 TargetARM32::CallingConv::ARM32_MAX_GPR_ARG> GPRArgs; 1518 TargetARM32::CallingConv::ARM32_MAX_GPR_ARG> GPRArgs;
1519 // Pair of Arg Operand -> stack offset. 1519 // Pair of Arg Operand -> stack offset.
1520 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; 1520 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs;
1521 int32_t ParameterAreaSizeBytes = 0; 1521 int32_t ParameterAreaSizeBytes = 0;
1522 1522
1523 // Classify each argument operand according to the location where the 1523 // Classify each argument operand according to the location where the
1524 // argument is passed. 1524 // argument is passed.
1525 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { 1525 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
1526 Operand *Arg = Instr->getArg(i); 1526 Operand *Arg = legalizeUndef(Instr->getArg(i));
1527 Type Ty = Arg->getType(); 1527 Type Ty = Arg->getType();
1528 bool InRegs = false; 1528 bool InRegs = false;
1529 if (isVectorType(Ty)) { 1529 if (isVectorType(Ty)) {
1530 UnimplementedError(Func->getContext()->getFlags()); 1530 UnimplementedError(Func->getContext()->getFlags());
1531 } else if (isFloatingType(Ty)) { 1531 } else if (isFloatingType(Ty)) {
1532 UnimplementedError(Func->getContext()->getFlags()); 1532 UnimplementedError(Func->getContext()->getFlags());
1533 } else if (Ty == IceType_i64) { 1533 } else if (Ty == IceType_i64) {
1534 std::pair<int32_t, int32_t> Regs; 1534 std::pair<int32_t, int32_t> Regs;
1535 if (CC.I64InRegs(&Regs)) { 1535 if (CC.I64InRegs(&Regs)) {
1536 InRegs = true; 1536 InRegs = true;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 } else { 1696 } else {
1697 _mov(Dest, ReturnReg); 1697 _mov(Dest, ReturnReg);
1698 } 1698 }
1699 } 1699 }
1700 } 1700 }
1701 } 1701 }
1702 1702
1703 void TargetARM32::lowerCast(const InstCast *Inst) { 1703 void TargetARM32::lowerCast(const InstCast *Inst) {
1704 InstCast::OpKind CastKind = Inst->getCastKind(); 1704 InstCast::OpKind CastKind = Inst->getCastKind();
1705 Variable *Dest = Inst->getDest(); 1705 Variable *Dest = Inst->getDest();
1706 Operand *Src0 = Inst->getSrc(0); 1706 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
1707 switch (CastKind) { 1707 switch (CastKind) {
1708 default: 1708 default:
1709 Func->setError("Cast type not supported"); 1709 Func->setError("Cast type not supported");
1710 return; 1710 return;
1711 case InstCast::Sext: { 1711 case InstCast::Sext: {
1712 if (isVectorType(Dest->getType())) { 1712 if (isVectorType(Dest->getType())) {
1713 UnimplementedError(Func->getContext()->getFlags()); 1713 UnimplementedError(Func->getContext()->getFlags());
1714 } else if (Dest->getType() == IceType_i64) { 1714 } else if (Dest->getType() == IceType_i64) {
1715 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2 1715 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2
1716 Constant *ShiftAmt = Ctx->getConstantInt32(31); 1716 Constant *ShiftAmt = Ctx->getConstantInt32(31);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 Variable *T = makeReg(Dest->getType()); 1801 Variable *T = makeReg(Dest->getType());
1802 _uxt(T, Src0R); 1802 _uxt(T, Src0R);
1803 _mov(Dest, T); 1803 _mov(Dest, T);
1804 } 1804 }
1805 break; 1805 break;
1806 } 1806 }
1807 case InstCast::Trunc: { 1807 case InstCast::Trunc: {
1808 if (isVectorType(Dest->getType())) { 1808 if (isVectorType(Dest->getType())) {
1809 UnimplementedError(Func->getContext()->getFlags()); 1809 UnimplementedError(Func->getContext()->getFlags());
1810 } else { 1810 } else {
1811 Operand *Src0 = Inst->getSrc(0);
1812 if (Src0->getType() == IceType_i64) 1811 if (Src0->getType() == IceType_i64)
1813 Src0 = loOperand(Src0); 1812 Src0 = loOperand(Src0);
1814 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); 1813 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex);
1815 // t1 = trunc Src0RF; Dest = t1 1814 // t1 = trunc Src0RF; Dest = t1
1816 Variable *T = makeReg(Dest->getType()); 1815 Variable *T = makeReg(Dest->getType());
1817 _mov(T, Src0RF); 1816 _mov(T, Src0RF);
1818 if (Dest->getType() == IceType_i1) 1817 if (Dest->getType() == IceType_i1)
1819 _and(T, T, Ctx->getConstantInt1(1)); 1818 _and(T, T, Ctx->getConstantInt1(1));
1820 _mov(Dest, T); 1819 _mov(Dest, T);
1821 } 1820 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 UnimplementedError(Func->getContext()->getFlags()); 1858 UnimplementedError(Func->getContext()->getFlags());
1860 } 1859 }
1861 1860
1862 void TargetARM32::lowerFcmp(const InstFcmp *Inst) { 1861 void TargetARM32::lowerFcmp(const InstFcmp *Inst) {
1863 (void)Inst; 1862 (void)Inst;
1864 UnimplementedError(Func->getContext()->getFlags()); 1863 UnimplementedError(Func->getContext()->getFlags());
1865 } 1864 }
1866 1865
1867 void TargetARM32::lowerIcmp(const InstIcmp *Inst) { 1866 void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
1868 Variable *Dest = Inst->getDest(); 1867 Variable *Dest = Inst->getDest();
1869 Operand *Src0 = Inst->getSrc(0); 1868 Operand *Src0 = legalizeUndef(Inst->getSrc(0));
1870 Operand *Src1 = Inst->getSrc(1); 1869 Operand *Src1 = legalizeUndef(Inst->getSrc(1));
1871 1870
1872 if (isVectorType(Dest->getType())) { 1871 if (isVectorType(Dest->getType())) {
1873 UnimplementedError(Func->getContext()->getFlags()); 1872 UnimplementedError(Func->getContext()->getFlags());
1874 return; 1873 return;
1875 } 1874 }
1876 1875
1877 // a=icmp cond, b, c ==> 1876 // a=icmp cond, b, c ==>
1878 // GCC does: 1877 // GCC does:
1879 // cmp b.hi, c.hi or cmp b.lo, c.lo 1878 // cmp b.hi, c.hi or cmp b.lo, c.lo
1880 // cmp.eq b.lo, c.lo sbcs t1, b.hi, c.hi 1879 // cmp.eq b.lo, c.lo sbcs t1, b.hi, c.hi
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2029 return; 2028 return;
2030 case Intrinsics::AtomicStore: { 2029 case Intrinsics::AtomicStore: {
2031 UnimplementedError(Func->getContext()->getFlags()); 2030 UnimplementedError(Func->getContext()->getFlags());
2032 return; 2031 return;
2033 } 2032 }
2034 case Intrinsics::Bswap: { 2033 case Intrinsics::Bswap: {
2035 Variable *Dest = Instr->getDest(); 2034 Variable *Dest = Instr->getDest();
2036 Operand *Val = Instr->getArg(0); 2035 Operand *Val = Instr->getArg(0);
2037 Type Ty = Val->getType(); 2036 Type Ty = Val->getType();
2038 if (Ty == IceType_i64) { 2037 if (Ty == IceType_i64) {
2038 Val = legalizeUndef(Val);
2039 Variable *Val_Lo = legalizeToVar(loOperand(Val)); 2039 Variable *Val_Lo = legalizeToVar(loOperand(Val));
2040 Variable *Val_Hi = legalizeToVar(hiOperand(Val)); 2040 Variable *Val_Hi = legalizeToVar(hiOperand(Val));
2041 Variable *T_Lo = makeReg(IceType_i32); 2041 Variable *T_Lo = makeReg(IceType_i32);
2042 Variable *T_Hi = makeReg(IceType_i32); 2042 Variable *T_Hi = makeReg(IceType_i32);
2043 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2043 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2044 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2044 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2045 _rev(T_Lo, Val_Lo); 2045 _rev(T_Lo, Val_Lo);
2046 _rev(T_Hi, Val_Hi); 2046 _rev(T_Hi, Val_Hi);
2047 _mov(DestLo, T_Hi); 2047 _mov(DestLo, T_Hi);
2048 _mov(DestHi, T_Lo); 2048 _mov(DestHi, T_Lo);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 } 2081 }
2082 return; 2082 return;
2083 } 2083 }
2084 case Intrinsics::Ctlz: { 2084 case Intrinsics::Ctlz: {
2085 // The "is zero undef" parameter is ignored and we always return 2085 // The "is zero undef" parameter is ignored and we always return
2086 // a well-defined value. 2086 // a well-defined value.
2087 Operand *Val = Instr->getArg(0); 2087 Operand *Val = Instr->getArg(0);
2088 Variable *ValLoR; 2088 Variable *ValLoR;
2089 Variable *ValHiR = nullptr; 2089 Variable *ValHiR = nullptr;
2090 if (Val->getType() == IceType_i64) { 2090 if (Val->getType() == IceType_i64) {
2091 Val = legalizeUndef(Val);
2091 ValLoR = legalizeToVar(loOperand(Val)); 2092 ValLoR = legalizeToVar(loOperand(Val));
2092 ValHiR = legalizeToVar(hiOperand(Val)); 2093 ValHiR = legalizeToVar(hiOperand(Val));
2093 } else { 2094 } else {
2094 ValLoR = legalizeToVar(Val); 2095 ValLoR = legalizeToVar(Val);
2095 } 2096 }
2096 lowerCLZ(Instr->getDest(), ValLoR, ValHiR); 2097 lowerCLZ(Instr->getDest(), ValLoR, ValHiR);
2097 return; 2098 return;
2098 } 2099 }
2099 case Intrinsics::Cttz: { 2100 case Intrinsics::Cttz: {
2100 // Essentially like Clz, but reverse the bits first. 2101 // Essentially like Clz, but reverse the bits first.
2101 Operand *Val = Instr->getArg(0); 2102 Operand *Val = Instr->getArg(0);
2102 Variable *ValLoR; 2103 Variable *ValLoR;
2103 Variable *ValHiR = nullptr; 2104 Variable *ValHiR = nullptr;
2104 if (Val->getType() == IceType_i64) { 2105 if (Val->getType() == IceType_i64) {
2106 Val = legalizeUndef(Val);
2105 ValLoR = legalizeToVar(loOperand(Val)); 2107 ValLoR = legalizeToVar(loOperand(Val));
2106 ValHiR = legalizeToVar(hiOperand(Val)); 2108 ValHiR = legalizeToVar(hiOperand(Val));
2107 Variable *TLo = makeReg(IceType_i32); 2109 Variable *TLo = makeReg(IceType_i32);
2108 Variable *THi = makeReg(IceType_i32); 2110 Variable *THi = makeReg(IceType_i32);
2109 _rbit(TLo, ValLoR); 2111 _rbit(TLo, ValLoR);
2110 _rbit(THi, ValHiR); 2112 _rbit(THi, ValHiR);
2111 ValLoR = THi; 2113 ValLoR = THi;
2112 ValHiR = TLo; 2114 ValHiR = TLo;
2113 } else { 2115 } else {
2114 ValLoR = legalizeToVar(Val); 2116 ValLoR = legalizeToVar(Val);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 2263
2262 void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) { 2264 void TargetARM32::lowerPhi(const InstPhi * /*Inst*/) {
2263 Func->setError("Phi found in regular instruction list"); 2265 Func->setError("Phi found in regular instruction list");
2264 } 2266 }
2265 2267
2266 void TargetARM32::lowerRet(const InstRet *Inst) { 2268 void TargetARM32::lowerRet(const InstRet *Inst) {
2267 Variable *Reg = nullptr; 2269 Variable *Reg = nullptr;
2268 if (Inst->hasRetValue()) { 2270 if (Inst->hasRetValue()) {
2269 Operand *Src0 = Inst->getRetValue(); 2271 Operand *Src0 = Inst->getRetValue();
2270 if (Src0->getType() == IceType_i64) { 2272 if (Src0->getType() == IceType_i64) {
2273 Src0 = legalizeUndef(Src0);
2271 Variable *R0 = legalizeToVar(loOperand(Src0), RegARM32::Reg_r0); 2274 Variable *R0 = legalizeToVar(loOperand(Src0), RegARM32::Reg_r0);
2272 Variable *R1 = legalizeToVar(hiOperand(Src0), RegARM32::Reg_r1); 2275 Variable *R1 = legalizeToVar(hiOperand(Src0), RegARM32::Reg_r1);
2273 Reg = R0; 2276 Reg = R0;
2274 Context.insert(InstFakeUse::create(Func, R1)); 2277 Context.insert(InstFakeUse::create(Func, R1));
2275 } else if (isScalarFloatingType(Src0->getType())) { 2278 } else if (isScalarFloatingType(Src0->getType())) {
2276 UnimplementedError(Func->getContext()->getFlags()); 2279 UnimplementedError(Func->getContext()->getFlags());
2277 } else if (isVectorType(Src0->getType())) { 2280 } else if (isVectorType(Src0->getType())) {
2278 UnimplementedError(Func->getContext()->getFlags()); 2281 UnimplementedError(Func->getContext()->getFlags());
2279 } else { 2282 } else {
2280 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex); 2283 Operand *Src0F = legalize(Src0, Legal_Reg | Legal_Flex);
(...skipping 30 matching lines...) Expand all
2311 UnimplementedError(Func->getContext()->getFlags()); 2314 UnimplementedError(Func->getContext()->getFlags());
2312 return; 2315 return;
2313 } 2316 }
2314 // TODO(jvoung): handle folding opportunities. 2317 // TODO(jvoung): handle folding opportunities.
2315 // cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t 2318 // cmp cond, #0; mov t, SrcF; mov_cond t, SrcT; mov dest, t
2316 Variable *CmpOpnd0 = legalizeToVar(Condition); 2319 Variable *CmpOpnd0 = legalizeToVar(Condition);
2317 Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32); 2320 Operand *CmpOpnd1 = Ctx->getConstantZero(IceType_i32);
2318 _cmp(CmpOpnd0, CmpOpnd1); 2321 _cmp(CmpOpnd0, CmpOpnd1);
2319 CondARM32::Cond Cond = CondARM32::NE; 2322 CondARM32::Cond Cond = CondARM32::NE;
2320 if (DestTy == IceType_i64) { 2323 if (DestTy == IceType_i64) {
2324 SrcT = legalizeUndef(SrcT);
2325 SrcF = legalizeUndef(SrcF);
2321 // Set the low portion. 2326 // Set the low portion.
2322 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2327 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2323 Variable *TLo = nullptr; 2328 Variable *TLo = nullptr;
2324 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex); 2329 Operand *SrcFLo = legalize(loOperand(SrcF), Legal_Reg | Legal_Flex);
2325 _mov(TLo, SrcFLo); 2330 _mov(TLo, SrcFLo);
2326 Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Flex); 2331 Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Flex);
2327 _mov_nonkillable(TLo, SrcTLo, Cond); 2332 _mov_nonkillable(TLo, SrcTLo, Cond);
2328 _mov(DestLo, TLo); 2333 _mov(DestLo, TLo);
2329 // Set the high portion. 2334 // Set the high portion.
2330 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2335 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
(...skipping 13 matching lines...) Expand all
2344 _mov(Dest, T); 2349 _mov(Dest, T);
2345 } 2350 }
2346 2351
2347 void TargetARM32::lowerStore(const InstStore *Inst) { 2352 void TargetARM32::lowerStore(const InstStore *Inst) {
2348 Operand *Value = Inst->getData(); 2353 Operand *Value = Inst->getData();
2349 Operand *Addr = Inst->getAddr(); 2354 Operand *Addr = Inst->getAddr();
2350 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType()); 2355 OperandARM32Mem *NewAddr = formMemoryOperand(Addr, Value->getType());
2351 Type Ty = NewAddr->getType(); 2356 Type Ty = NewAddr->getType();
2352 2357
2353 if (Ty == IceType_i64) { 2358 if (Ty == IceType_i64) {
2359 Value = legalizeUndef(Value);
2354 Variable *ValueHi = legalizeToVar(hiOperand(Value)); 2360 Variable *ValueHi = legalizeToVar(hiOperand(Value));
2355 Variable *ValueLo = legalizeToVar(loOperand(Value)); 2361 Variable *ValueLo = legalizeToVar(loOperand(Value));
2356 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr))); 2362 _str(ValueHi, llvm::cast<OperandARM32Mem>(hiOperand(NewAddr)));
2357 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr))); 2363 _str(ValueLo, llvm::cast<OperandARM32Mem>(loOperand(NewAddr)));
2358 } else if (isVectorType(Ty)) { 2364 } else if (isVectorType(Ty)) {
2359 UnimplementedError(Func->getContext()->getFlags()); 2365 UnimplementedError(Func->getContext()->getFlags());
2360 } else { 2366 } else {
2361 Variable *ValueR = legalizeToVar(Value); 2367 Variable *ValueR = legalizeToVar(Value);
2362 _str(ValueR, NewAddr); 2368 _str(ValueR, NewAddr);
2363 } 2369 }
2364 } 2370 }
2365 2371
2366 void TargetARM32::doAddressOptStore() { 2372 void TargetARM32::doAddressOptStore() {
2367 UnimplementedError(Func->getContext()->getFlags()); 2373 UnimplementedError(Func->getContext()->getFlags());
2368 } 2374 }
2369 2375
2370 void TargetARM32::lowerSwitch(const InstSwitch *Inst) { 2376 void TargetARM32::lowerSwitch(const InstSwitch *Inst) {
2371 // This implements the most naive possible lowering. 2377 // This implements the most naive possible lowering.
2372 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default 2378 // cmp a,val[0]; jeq label[0]; cmp a,val[1]; jeq label[1]; ... jmp default
2373 Operand *Src0 = Inst->getComparison(); 2379 Operand *Src0 = Inst->getComparison();
2374 SizeT NumCases = Inst->getNumCases(); 2380 SizeT NumCases = Inst->getNumCases();
2375 if (Src0->getType() == IceType_i64) { 2381 if (Src0->getType() == IceType_i64) {
2376 // TODO(jvoung): handle and test undef for Src0 2382 Src0 = legalizeUndef(Src0);
2377 Variable *Src0Lo = legalizeToVar(loOperand(Src0)); 2383 Variable *Src0Lo = legalizeToVar(loOperand(Src0));
2378 Variable *Src0Hi = legalizeToVar(hiOperand(Src0)); 2384 Variable *Src0Hi = legalizeToVar(hiOperand(Src0));
2379 for (SizeT I = 0; I < NumCases; ++I) { 2385 for (SizeT I = 0; I < NumCases; ++I) {
2380 Operand *ValueLo = Ctx->getConstantInt32(Inst->getValue(I)); 2386 Operand *ValueLo = Ctx->getConstantInt32(Inst->getValue(I));
2381 Operand *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32); 2387 Operand *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32);
2382 ValueLo = legalize(ValueLo, Legal_Reg | Legal_Flex); 2388 ValueLo = legalize(ValueLo, Legal_Reg | Legal_Flex);
2383 ValueHi = legalize(ValueHi, Legal_Reg | Legal_Flex); 2389 ValueHi = legalize(ValueHi, Legal_Reg | Legal_Flex);
2384 _cmp(Src0Lo, ValueLo); 2390 _cmp(Src0Lo, ValueLo);
2385 _cmp(Src0Hi, ValueHi, CondARM32::EQ); 2391 _cmp(Src0Hi, ValueHi, CondARM32::EQ);
2386 _br(Inst->getLabel(I), CondARM32::EQ); 2392 _br(Inst->getLabel(I), CondARM32::EQ);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2437 } else { 2443 } else {
2438 // Mov's Src operand can really only be the flexible second operand type 2444 // Mov's Src operand can really only be the flexible second operand type
2439 // or a register. Users should guarantee that. 2445 // or a register. Users should guarantee that.
2440 _mov(Reg, Src); 2446 _mov(Reg, Src);
2441 } 2447 }
2442 return Reg; 2448 return Reg;
2443 } 2449 }
2444 2450
2445 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, 2451 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed,
2446 int32_t RegNum) { 2452 int32_t RegNum) {
2453 Type Ty = From->getType();
2447 // Assert that a physical register is allowed. To date, all calls 2454 // Assert that a physical register is allowed. To date, all calls
2448 // to legalize() allow a physical register. Legal_Flex converts 2455 // to legalize() allow a physical register. Legal_Flex converts
2449 // registers to the right type OperandARM32FlexReg as needed. 2456 // registers to the right type OperandARM32FlexReg as needed.
2450 assert(Allowed & Legal_Reg); 2457 assert(Allowed & Legal_Reg);
2451 // Go through the various types of operands: 2458 // Go through the various types of operands:
2452 // OperandARM32Mem, OperandARM32Flex, Constant, and Variable. 2459 // OperandARM32Mem, OperandARM32Flex, Constant, and Variable.
2453 // Given the above assertion, if type of operand is not legal 2460 // Given the above assertion, if type of operand is not legal
2454 // (e.g., OperandARM32Mem and !Legal_Mem), we can always copy 2461 // (e.g., OperandARM32Mem and !Legal_Mem), we can always copy
2455 // to a register. 2462 // to a register.
2456 if (auto Mem = llvm::dyn_cast<OperandARM32Mem>(From)) { 2463 if (auto Mem = llvm::dyn_cast<OperandARM32Mem>(From)) {
2457 // Before doing anything with a Mem operand, we need to ensure 2464 // Before doing anything with a Mem operand, we need to ensure
2458 // that the Base and Index components are in physical registers. 2465 // that the Base and Index components are in physical registers.
2459 Variable *Base = Mem->getBase(); 2466 Variable *Base = Mem->getBase();
2460 Variable *Index = Mem->getIndex(); 2467 Variable *Index = Mem->getIndex();
2461 Variable *RegBase = nullptr; 2468 Variable *RegBase = nullptr;
2462 Variable *RegIndex = nullptr; 2469 Variable *RegIndex = nullptr;
2463 if (Base) { 2470 if (Base) {
2464 RegBase = legalizeToVar(Base); 2471 RegBase = legalizeToVar(Base);
2465 } 2472 }
2466 if (Index) { 2473 if (Index) {
2467 RegIndex = legalizeToVar(Index); 2474 RegIndex = legalizeToVar(Index);
2468 } 2475 }
2469 // Create a new operand if there was a change. 2476 // Create a new operand if there was a change.
2470 if (Base != RegBase || Index != RegIndex) { 2477 if (Base != RegBase || Index != RegIndex) {
2471 // There is only a reg +/- reg or reg + imm form. 2478 // There is only a reg +/- reg or reg + imm form.
2472 // Figure out which to re-create. 2479 // Figure out which to re-create.
2473 if (Mem->isRegReg()) { 2480 if (Mem->isRegReg()) {
2474 Mem = OperandARM32Mem::create(Func, Mem->getType(), RegBase, RegIndex, 2481 Mem = OperandARM32Mem::create(Func, Ty, RegBase, RegIndex,
2475 Mem->getShiftOp(), Mem->getShiftAmt(), 2482 Mem->getShiftOp(), Mem->getShiftAmt(),
2476 Mem->getAddrMode()); 2483 Mem->getAddrMode());
2477 } else { 2484 } else {
2478 Mem = OperandARM32Mem::create(Func, Mem->getType(), RegBase, 2485 Mem = OperandARM32Mem::create(Func, Ty, RegBase, Mem->getOffset(),
2479 Mem->getOffset(), Mem->getAddrMode()); 2486 Mem->getAddrMode());
2480 } 2487 }
2481 } 2488 }
2482 if (!(Allowed & Legal_Mem)) { 2489 if (!(Allowed & Legal_Mem)) {
2483 Type Ty = Mem->getType();
2484 Variable *Reg = makeReg(Ty, RegNum); 2490 Variable *Reg = makeReg(Ty, RegNum);
2485 _ldr(Reg, Mem); 2491 _ldr(Reg, Mem);
2486 From = Reg; 2492 From = Reg;
2487 } else { 2493 } else {
2488 From = Mem; 2494 From = Mem;
2489 } 2495 }
2490 return From; 2496 return From;
2491 } 2497 }
2492 2498
2493 if (auto Flex = llvm::dyn_cast<OperandARM32Flex>(From)) { 2499 if (auto Flex = llvm::dyn_cast<OperandARM32Flex>(From)) {
2494 if (!(Allowed & Legal_Flex)) { 2500 if (!(Allowed & Legal_Flex)) {
2495 if (auto FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Flex)) { 2501 if (auto FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Flex)) {
2496 if (FlexReg->getShiftOp() == OperandARM32::kNoShift) { 2502 if (FlexReg->getShiftOp() == OperandARM32::kNoShift) {
2497 From = FlexReg->getReg(); 2503 From = FlexReg->getReg();
2498 // Fall through and let From be checked as a Variable below, 2504 // Fall through and let From be checked as a Variable below,
2499 // where it may or may not need a register. 2505 // where it may or may not need a register.
2500 } else { 2506 } else {
2501 return copyToReg(Flex, RegNum); 2507 return copyToReg(Flex, RegNum);
2502 } 2508 }
2503 } else { 2509 } else {
2504 return copyToReg(Flex, RegNum); 2510 return copyToReg(Flex, RegNum);
2505 } 2511 }
2506 } else { 2512 } else {
2507 return From; 2513 return From;
2508 } 2514 }
2509 } 2515 }
2510 2516
2511 if (llvm::isa<Constant>(From)) { 2517 if (llvm::isa<Constant>(From)) {
2512 if (llvm::isa<ConstantUndef>(From)) { 2518 if (llvm::isa<ConstantUndef>(From)) {
2513 // Lower undefs to zero. Another option is to lower undefs to an 2519 From = legalizeUndef(From, RegNum);
2514 // uninitialized register; however, using an uninitialized register 2520 if (isVectorType(Ty))
2515 // results in less predictable code. 2521 return From;
2516 if (isVectorType(From->getType()))
2517 return makeVectorOfZeros(From->getType(), RegNum);
2518 From = Ctx->getConstantZero(From->getType());
2519 } 2522 }
2520 // There should be no constants of vector type (other than undef). 2523 // There should be no constants of vector type (other than undef).
2521 assert(!isVectorType(From->getType())); 2524 assert(!isVectorType(Ty));
2522 bool CanBeFlex = Allowed & Legal_Flex; 2525 bool CanBeFlex = Allowed & Legal_Flex;
2523 if (auto C32 = llvm::dyn_cast<ConstantInteger32>(From)) { 2526 if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
2524 uint32_t RotateAmt; 2527 uint32_t RotateAmt;
2525 uint32_t Immed_8; 2528 uint32_t Immed_8;
2526 uint32_t Value = static_cast<uint32_t>(C32->getValue()); 2529 uint32_t Value = static_cast<uint32_t>(C32->getValue());
2527 // Check if the immediate will fit in a Flexible second operand, 2530 // Check if the immediate will fit in a Flexible second operand,
2528 // if a Flexible second operand is allowed. We need to know the exact 2531 // if a Flexible second operand is allowed. We need to know the exact
2529 // value, so that rules out relocatable constants. 2532 // value, so that rules out relocatable constants.
2530 // Also try the inverse and use MVN if possible. 2533 // Also try the inverse and use MVN if possible.
2531 if (CanBeFlex && 2534 if (CanBeFlex &&
2532 OperandARM32FlexImm::canHoldImm(Value, &RotateAmt, &Immed_8)) { 2535 OperandARM32FlexImm::canHoldImm(Value, &RotateAmt, &Immed_8)) {
2533 return OperandARM32FlexImm::create(Func, From->getType(), Immed_8, 2536 return OperandARM32FlexImm::create(Func, Ty, Immed_8, RotateAmt);
2534 RotateAmt);
2535 } else if (CanBeFlex && OperandARM32FlexImm::canHoldImm( 2537 } else if (CanBeFlex && OperandARM32FlexImm::canHoldImm(
2536 ~Value, &RotateAmt, &Immed_8)) { 2538 ~Value, &RotateAmt, &Immed_8)) {
2537 auto InvertedFlex = OperandARM32FlexImm::create(Func, From->getType(), 2539 auto InvertedFlex =
2538 Immed_8, RotateAmt); 2540 OperandARM32FlexImm::create(Func, Ty, Immed_8, RotateAmt);
2539 Type Ty = From->getType();
2540 Variable *Reg = makeReg(Ty, RegNum); 2541 Variable *Reg = makeReg(Ty, RegNum);
2541 _mvn(Reg, InvertedFlex); 2542 _mvn(Reg, InvertedFlex);
2542 return Reg; 2543 return Reg;
2543 } else { 2544 } else {
2544 // Do a movw/movt to a register. 2545 // Do a movw/movt to a register.
2545 Type Ty = From->getType();
2546 Variable *Reg = makeReg(Ty, RegNum); 2546 Variable *Reg = makeReg(Ty, RegNum);
2547 uint32_t UpperBits = (Value >> 16) & 0xFFFF; 2547 uint32_t UpperBits = (Value >> 16) & 0xFFFF;
2548 _movw(Reg, 2548 _movw(Reg,
2549 UpperBits != 0 ? Ctx->getConstantInt32(Value & 0xFFFF) : C32); 2549 UpperBits != 0 ? Ctx->getConstantInt32(Value & 0xFFFF) : C32);
2550 if (UpperBits != 0) { 2550 if (UpperBits != 0) {
2551 _movt(Reg, Ctx->getConstantInt32(UpperBits)); 2551 _movt(Reg, Ctx->getConstantInt32(UpperBits));
2552 } 2552 }
2553 return Reg; 2553 return Reg;
2554 } 2554 }
2555 } else if (auto C = llvm::dyn_cast<ConstantRelocatable>(From)) { 2555 } else if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
2556 Type Ty = From->getType();
2557 Variable *Reg = makeReg(Ty, RegNum); 2556 Variable *Reg = makeReg(Ty, RegNum);
2558 _movw(Reg, C); 2557 _movw(Reg, C);
2559 _movt(Reg, C); 2558 _movt(Reg, C);
2560 return Reg; 2559 return Reg;
2561 } else { 2560 } else {
2562 // Load floats/doubles from literal pool. 2561 // Load floats/doubles from literal pool.
2563 UnimplementedError(Func->getContext()->getFlags()); 2562 UnimplementedError(Func->getContext()->getFlags());
2564 From = copyToReg(From, RegNum); 2563 From = copyToReg(From, RegNum);
2565 } 2564 }
2566 return From; 2565 return From;
(...skipping 12 matching lines...) Expand all
2579 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { 2578 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) {
2580 From = copyToReg(From, RegNum); 2579 From = copyToReg(From, RegNum);
2581 } 2580 }
2582 return From; 2581 return From;
2583 } 2582 }
2584 llvm_unreachable("Unhandled operand kind in legalize()"); 2583 llvm_unreachable("Unhandled operand kind in legalize()");
2585 2584
2586 return From; 2585 return From;
2587 } 2586 }
2588 2587
2589 // Provide a trivial wrapper to legalize() for this common usage. 2588 /// Provide a trivial wrapper to legalize() for this common usage.
2590 Variable *TargetARM32::legalizeToVar(Operand *From, int32_t RegNum) { 2589 Variable *TargetARM32::legalizeToVar(Operand *From, int32_t RegNum) {
2591 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); 2590 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
2592 } 2591 }
2593 2592
2593 /// Legalize undef values to concrete values.
2594 Operand *TargetARM32::legalizeUndef(Operand *From, int32_t RegNum) {
2595 Type Ty = From->getType();
2596 if (llvm::isa<ConstantUndef>(From)) {
2597 // Lower undefs to zero. Another option is to lower undefs to an
2598 // uninitialized register; however, using an uninitialized register
2599 // results in less predictable code.
2600 //
2601 // If in the future the implementation is changed to lower undef
2602 // values to uninitialized registers, a FakeDef will be needed:
2603 // Context.insert(InstFakeDef::create(Func, Reg));
2604 // This is in order to ensure that the live range of Reg is not
2605 // overestimated. If the constant being lowered is a 64 bit value,
2606 // then the result should be split and the lo and hi components will
2607 // need to go in uninitialized registers.
2608 if (isVectorType(Ty))
2609 return makeVectorOfZeros(Ty, RegNum);
2610 return Ctx->getConstantZero(Ty);
2611 }
2612 return From;
2613 }
2614
2594 OperandARM32Mem *TargetARM32::formMemoryOperand(Operand *Operand, Type Ty) { 2615 OperandARM32Mem *TargetARM32::formMemoryOperand(Operand *Operand, Type Ty) {
2595 OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand); 2616 OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand);
2596 // It may be the case that address mode optimization already creates 2617 // It may be the case that address mode optimization already creates
2597 // an OperandARM32Mem, so in that case it wouldn't need another level 2618 // an OperandARM32Mem, so in that case it wouldn't need another level
2598 // of transformation. 2619 // of transformation.
2599 if (Mem) { 2620 if (Mem) {
2600 return llvm::cast<OperandARM32Mem>(legalize(Mem)); 2621 return llvm::cast<OperandARM32Mem>(legalize(Mem));
2601 } 2622 }
2602 // If we didn't do address mode optimization, then we only 2623 // If we didn't do address mode optimization, then we only
2603 // have a base/offset to work with. ARM always requires a base 2624 // have a base/offset to work with. ARM always requires a base
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2746 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; 2767 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n";
2747 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { 2768 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) {
2748 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; 2769 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n";
2749 } 2770 }
2750 // Technically R9 is used for TLS with Sandboxing, and we reserve it. 2771 // Technically R9 is used for TLS with Sandboxing, and we reserve it.
2751 // However, for compatibility with current NaCl LLVM, don't claim that. 2772 // However, for compatibility with current NaCl LLVM, don't claim that.
2752 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 2773 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
2753 } 2774 }
2754 2775
2755 } // end of namespace Ice 2776 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | src/IceTargetLoweringX86Base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698