| OLD | NEW |
| 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 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 return; | 447 return; |
| 448 case Inst::Arithmetic: { | 448 case Inst::Arithmetic: { |
| 449 Variable *Dest = Instr->getDest(); | 449 Variable *Dest = Instr->getDest(); |
| 450 const Type DestTy = Dest->getType(); | 450 const Type DestTy = Dest->getType(); |
| 451 const InstArithmetic::OpKind Op = | 451 const InstArithmetic::OpKind Op = |
| 452 llvm::cast<InstArithmetic>(Instr)->getOp(); | 452 llvm::cast<InstArithmetic>(Instr)->getOp(); |
| 453 if (isVectorType(DestTy)) { | 453 if (isVectorType(DestTy)) { |
| 454 switch (Op) { | 454 switch (Op) { |
| 455 default: | 455 default: |
| 456 break; | 456 break; |
| 457 case InstArithmetic::Ashr: | |
| 458 case InstArithmetic::Fdiv: | 457 case InstArithmetic::Fdiv: |
| 459 case InstArithmetic::Frem: | 458 case InstArithmetic::Frem: |
| 460 case InstArithmetic::Lshr: | |
| 461 case InstArithmetic::Sdiv: | 459 case InstArithmetic::Sdiv: |
| 462 case InstArithmetic::Shl: | |
| 463 case InstArithmetic::Srem: | 460 case InstArithmetic::Srem: |
| 464 case InstArithmetic::Udiv: | 461 case InstArithmetic::Udiv: |
| 465 case InstArithmetic::Urem: | 462 case InstArithmetic::Urem: |
| 466 scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1)); | 463 scalarizeArithmetic(Op, Dest, Instr->getSrc(0), Instr->getSrc(1)); |
| 467 Instr->setDeleted(); | 464 Instr->setDeleted(); |
| 468 return; | 465 return; |
| 469 } | 466 } |
| 470 } | 467 } |
| 471 switch (DestTy) { | 468 switch (DestTy) { |
| 472 default: | 469 default: |
| (...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1953 | 1950 |
| 1954 // ARM32 address modes: | 1951 // ARM32 address modes: |
| 1955 // ld/st i[8|16|32]: [reg], [reg +/- imm12], [pc +/- imm12], | 1952 // ld/st i[8|16|32]: [reg], [reg +/- imm12], [pc +/- imm12], |
| 1956 // [reg +/- reg << shamt5] | 1953 // [reg +/- reg << shamt5] |
| 1957 // ld/st f[32|64] : [reg], [reg +/- imm8] , [pc +/- imm8] | 1954 // ld/st f[32|64] : [reg], [reg +/- imm8] , [pc +/- imm8] |
| 1958 // ld/st vectors : [reg] | 1955 // ld/st vectors : [reg] |
| 1959 // | 1956 // |
| 1960 // For now, we don't handle address modes with Relocatables. | 1957 // For now, we don't handle address modes with Relocatables. |
| 1961 namespace { | 1958 namespace { |
| 1962 // MemTraits contains per-type valid address mode information. | 1959 // MemTraits contains per-type valid address mode information. |
| 1963 #define X(tag, elementty, int_width, vec_width, sbits, ubits, rraddr, shaddr) \ | 1960 #define X(tag, elementty, int_width, fp_width, uvec_width, svec_width, sbits, \ |
| 1961 ubits, rraddr, shaddr) \ |
| 1964 static_assert(!(shaddr) || rraddr, "Check ICETYPEARM32_TABLE::" #tag); | 1962 static_assert(!(shaddr) || rraddr, "Check ICETYPEARM32_TABLE::" #tag); |
| 1965 ICETYPEARM32_TABLE | 1963 ICETYPEARM32_TABLE |
| 1966 #undef X | 1964 #undef X |
| 1967 | 1965 |
| 1968 static const struct { | 1966 static const struct { |
| 1969 int32_t ValidImmMask; | 1967 int32_t ValidImmMask; |
| 1970 bool CanHaveImm; | 1968 bool CanHaveImm; |
| 1971 bool CanHaveIndex; | 1969 bool CanHaveIndex; |
| 1972 bool CanHaveShiftedIndex; | 1970 bool CanHaveShiftedIndex; |
| 1973 } MemTraits[] = { | 1971 } MemTraits[] = { |
| 1974 #define X(tag, elementty, int_width, vec_width, sbits, ubits, rraddr, shaddr) \ | 1972 #define X(tag, elementty, int_width, fp_width, uvec_width, svec_width, sbits, \ |
| 1973 ubits, rraddr, shaddr) \ |
| 1975 { (1 << ubits) - 1, (ubits) > 0, rraddr, shaddr, } \ | 1974 { (1 << ubits) - 1, (ubits) > 0, rraddr, shaddr, } \ |
| 1976 , | 1975 , |
| 1977 ICETYPEARM32_TABLE | 1976 ICETYPEARM32_TABLE |
| 1978 #undef X | 1977 #undef X |
| 1979 }; | 1978 }; |
| 1980 static constexpr SizeT MemTraitsSize = llvm::array_lengthof(MemTraits); | 1979 static constexpr SizeT MemTraitsSize = llvm::array_lengthof(MemTraits); |
| 1981 } // end of anonymous namespace | 1980 } // end of anonymous namespace |
| 1982 | 1981 |
| 1983 OperandARM32Mem * | 1982 OperandARM32Mem * |
| 1984 TargetARM32::PostLoweringLegalizer::legalizeMemOperand(OperandARM32Mem *Mem, | 1983 TargetARM32::PostLoweringLegalizer::legalizeMemOperand(OperandARM32Mem *Mem, |
| (...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3113 lowerInt64Arithmetic(Instr->getOp(), Instr->getDest(), Src0, Src1); | 3112 lowerInt64Arithmetic(Instr->getOp(), Instr->getDest(), Src0, Src1); |
| 3114 return; | 3113 return; |
| 3115 } | 3114 } |
| 3116 | 3115 |
| 3117 if (isVectorType(DestTy)) { | 3116 if (isVectorType(DestTy)) { |
| 3118 switch (Instr->getOp()) { | 3117 switch (Instr->getOp()) { |
| 3119 default: | 3118 default: |
| 3120 UnimplementedLoweringError(this, Instr); | 3119 UnimplementedLoweringError(this, Instr); |
| 3121 return; | 3120 return; |
| 3122 // Explicitly whitelist vector instructions we have implemented/enabled. | 3121 // Explicitly whitelist vector instructions we have implemented/enabled. |
| 3122 case InstArithmetic::Add: |
| 3123 case InstArithmetic::And: |
| 3124 case InstArithmetic::Ashr: |
| 3123 case InstArithmetic::Fadd: | 3125 case InstArithmetic::Fadd: |
| 3124 case InstArithmetic::Add: | 3126 case InstArithmetic::Fmul: |
| 3125 case InstArithmetic::Fsub: | 3127 case InstArithmetic::Fsub: |
| 3128 case InstArithmetic::Lshr: |
| 3129 case InstArithmetic::Mul: |
| 3130 case InstArithmetic::Or: |
| 3131 case InstArithmetic::Shl: |
| 3126 case InstArithmetic::Sub: | 3132 case InstArithmetic::Sub: |
| 3127 case InstArithmetic::And: | |
| 3128 case InstArithmetic::Or: | |
| 3129 case InstArithmetic::Xor: | 3133 case InstArithmetic::Xor: |
| 3130 case InstArithmetic::Fmul: | |
| 3131 case InstArithmetic::Mul: | |
| 3132 break; | 3134 break; |
| 3133 } | 3135 } |
| 3134 } | 3136 } |
| 3135 | 3137 |
| 3136 Variable *T = makeReg(DestTy); | 3138 Variable *T = makeReg(DestTy); |
| 3137 | 3139 |
| 3138 // * Handle div/rem separately. They require a non-legalized Src1 to inspect | 3140 // * Handle div/rem separately. They require a non-legalized Src1 to inspect |
| 3139 // whether or not Src1 is a non-zero constant. Once legalized it is more | 3141 // whether or not Src1 is a non-zero constant. Once legalized it is more |
| 3140 // difficult to determine (constant may be moved to a register). | 3142 // difficult to determine (constant may be moved to a register). |
| 3141 // * Handle floating point arithmetic separately: they require Src1 to be | 3143 // * Handle floating point arithmetic separately: they require Src1 to be |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3441 if (isVectorType(DestTy)) { | 3443 if (isVectorType(DestTy)) { |
| 3442 _vmul(T, Src0R, Src1R); | 3444 _vmul(T, Src0R, Src1R); |
| 3443 } else { | 3445 } else { |
| 3444 _mul(T, Src0R, Src1R); | 3446 _mul(T, Src0R, Src1R); |
| 3445 } | 3447 } |
| 3446 _mov(Dest, T); | 3448 _mov(Dest, T); |
| 3447 return; | 3449 return; |
| 3448 } | 3450 } |
| 3449 case InstArithmetic::Shl: { | 3451 case InstArithmetic::Shl: { |
| 3450 Variable *Src0R = Srcs.unswappedSrc0R(this); | 3452 Variable *Src0R = Srcs.unswappedSrc0R(this); |
| 3451 Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); | 3453 if (!isVectorType(T->getType())) { |
| 3452 _lsl(T, Src0R, Src1R); | 3454 Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); |
| 3455 _lsl(T, Src0R, Src1R); |
| 3456 } else { |
| 3457 auto *Src1R = Srcs.unswappedSrc1R(this); |
| 3458 _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned); |
| 3459 } |
| 3453 _mov(Dest, T); | 3460 _mov(Dest, T); |
| 3454 return; | 3461 return; |
| 3455 } | 3462 } |
| 3456 case InstArithmetic::Lshr: { | 3463 case InstArithmetic::Lshr: { |
| 3457 Variable *Src0R = Srcs.unswappedSrc0R(this); | 3464 Variable *Src0R = Srcs.unswappedSrc0R(this); |
| 3458 if (DestTy != IceType_i32) { | 3465 if (!isVectorType(T->getType())) { |
| 3459 _uxt(Src0R, Src0R); | 3466 Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); |
| 3467 if (DestTy != IceType_i32) { |
| 3468 _uxt(Src0R, Src0R); |
| 3469 } |
| 3470 _lsr(T, Src0R, Src1R); |
| 3471 } else { |
| 3472 auto *Src1R = Srcs.unswappedSrc1R(this); |
| 3473 auto *Src1RNeg = makeReg(Src1R->getType()); |
| 3474 _vneg(Src1RNeg, Src1R); |
| 3475 _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Unsigned); |
| 3460 } | 3476 } |
| 3461 _lsr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); | |
| 3462 _mov(Dest, T); | 3477 _mov(Dest, T); |
| 3463 return; | 3478 return; |
| 3464 } | 3479 } |
| 3465 case InstArithmetic::Ashr: { | 3480 case InstArithmetic::Ashr: { |
| 3466 Variable *Src0R = Srcs.unswappedSrc0R(this); | 3481 Variable *Src0R = Srcs.unswappedSrc0R(this); |
| 3467 if (DestTy != IceType_i32) { | 3482 if (!isVectorType(T->getType())) { |
| 3468 _sxt(Src0R, Src0R); | 3483 if (DestTy != IceType_i32) { |
| 3484 _sxt(Src0R, Src0R); |
| 3485 } |
| 3486 _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); |
| 3487 } else { |
| 3488 auto *Src1R = Srcs.unswappedSrc1R(this); |
| 3489 auto *Src1RNeg = makeReg(Src1R->getType()); |
| 3490 _vneg(Src1RNeg, Src1R); |
| 3491 _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Signed); |
| 3469 } | 3492 } |
| 3470 _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); | |
| 3471 _mov(Dest, T); | 3493 _mov(Dest, T); |
| 3472 return; | 3494 return; |
| 3473 } | 3495 } |
| 3474 case InstArithmetic::Udiv: | 3496 case InstArithmetic::Udiv: |
| 3475 case InstArithmetic::Sdiv: | 3497 case InstArithmetic::Sdiv: |
| 3476 case InstArithmetic::Urem: | 3498 case InstArithmetic::Urem: |
| 3477 case InstArithmetic::Srem: | 3499 case InstArithmetic::Srem: |
| 3478 llvm::report_fatal_error( | 3500 llvm::report_fatal_error( |
| 3479 "Integer div/rem should have been handled earlier."); | 3501 "Integer div/rem should have been handled earlier."); |
| 3480 return; | 3502 return; |
| (...skipping 3431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6912 // However, for compatibility with current NaCl LLVM, don't claim that. | 6934 // However, for compatibility with current NaCl LLVM, don't claim that. |
| 6913 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6935 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
| 6914 } | 6936 } |
| 6915 | 6937 |
| 6916 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6938 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
| 6917 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6939 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
| 6918 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6940 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
| 6919 | 6941 |
| 6920 } // end of namespace ARM32 | 6942 } // end of namespace ARM32 |
| 6921 } // end of namespace Ice | 6943 } // end of namespace Ice |
| OLD | NEW |