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 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 if (Ctx->getFlags().shouldDoNopInsertion()) { | 755 if (Ctx->getFlags().shouldDoNopInsertion()) { |
756 Func->doNopInsertion(); | 756 Func->doNopInsertion(); |
757 } | 757 } |
758 } | 758 } |
759 | 759 |
760 uint32_t TargetARM32::getStackAlignment() const { | 760 uint32_t TargetARM32::getStackAlignment() const { |
761 return ARM32_STACK_ALIGNMENT_BYTES; | 761 return ARM32_STACK_ALIGNMENT_BYTES; |
762 } | 762 } |
763 | 763 |
764 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { | 764 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { |
765 if (InstARM32Br *Br = llvm::dyn_cast<InstARM32Br>(I)) { | 765 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { |
766 return Br->optimizeBranch(NextNode); | 766 return Br->optimizeBranch(NextNode); |
767 } | 767 } |
768 return false; | 768 return false; |
769 } | 769 } |
770 | 770 |
771 const char *RegARM32::RegNames[] = { | 771 const char *RegARM32::RegNames[] = { |
772 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ | 772 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ |
773 isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 773 isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
774 name, | 774 name, |
775 REGARM32_TABLE | 775 REGARM32_TABLE |
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1936 break; | 1936 break; |
1937 } | 1937 } |
1938 case IceType_i64: { | 1938 case IceType_i64: { |
1939 Variable *T = makeReg(IceType_i32); | 1939 Variable *T = makeReg(IceType_i32); |
1940 _orrs(T, SrcLoReg, legalize(SrcHi, Legal_Reg | Legal_Flex)); | 1940 _orrs(T, SrcLoReg, legalize(SrcHi, Legal_Reg | Legal_Flex)); |
1941 // T isn't going to be used, but we need the side-effect of setting flags | 1941 // T isn't going to be used, but we need the side-effect of setting flags |
1942 // from this operation. | 1942 // from this operation. |
1943 Context.insert(InstFakeUse::create(Func, T)); | 1943 Context.insert(InstFakeUse::create(Func, T)); |
1944 } | 1944 } |
1945 } | 1945 } |
1946 InstARM32Label *Label = InstARM32Label::create(Func, this); | 1946 auto *Label = InstARM32Label::create(Func, this); |
1947 _br(Label, CondARM32::NE); | 1947 _br(Label, CondARM32::NE); |
1948 _trap(); | 1948 _trap(); |
1949 Context.insert(Label); | 1949 Context.insert(Label); |
1950 } | 1950 } |
1951 | 1951 |
1952 void TargetARM32::lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R, | 1952 void TargetARM32::lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R, |
1953 Operand *Src1, ExtInstr ExtFunc, | 1953 Operand *Src1, ExtInstr ExtFunc, |
1954 DivInstr DivFunc, bool IsRemainder) { | 1954 DivInstr DivFunc, bool IsRemainder) { |
1955 div0Check(Dest->getType(), Src1, nullptr); | 1955 div0Check(Dest->getType(), Src1, nullptr); |
1956 Variable *Src1R = legalizeToReg(Src1); | 1956 Variable *Src1R = legalizeToReg(Src1); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2206 } | 2206 } |
2207 | 2207 |
2208 void TargetARM32::lowerInt64Arithmetic(InstArithmetic::OpKind Op, | 2208 void TargetARM32::lowerInt64Arithmetic(InstArithmetic::OpKind Op, |
2209 Variable *Dest, Operand *Src0, | 2209 Variable *Dest, Operand *Src0, |
2210 Operand *Src1) { | 2210 Operand *Src1) { |
2211 Int32Operands SrcsLo(loOperand(Src0), loOperand(Src1)); | 2211 Int32Operands SrcsLo(loOperand(Src0), loOperand(Src1)); |
2212 Int32Operands SrcsHi(hiOperand(Src0), hiOperand(Src1)); | 2212 Int32Operands SrcsHi(hiOperand(Src0), hiOperand(Src1)); |
2213 assert(SrcsLo.swappedOperands() == SrcsHi.swappedOperands()); | 2213 assert(SrcsLo.swappedOperands() == SrcsHi.swappedOperands()); |
2214 assert(SrcsLo.hasConstOperand() == SrcsHi.hasConstOperand()); | 2214 assert(SrcsLo.hasConstOperand() == SrcsHi.hasConstOperand()); |
2215 | 2215 |
2216 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2216 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
2217 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2217 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
2218 Variable *T_Lo = makeReg(DestLo->getType()); | 2218 Variable *T_Lo = makeReg(DestLo->getType()); |
2219 Variable *T_Hi = makeReg(DestHi->getType()); | 2219 Variable *T_Hi = makeReg(DestHi->getType()); |
2220 | 2220 |
2221 switch (Op) { | 2221 switch (Op) { |
2222 case InstArithmetic::_num: | 2222 case InstArithmetic::_num: |
2223 llvm::report_fatal_error("Unknown arithmetic operator"); | 2223 llvm::report_fatal_error("Unknown arithmetic operator"); |
2224 return; | 2224 return; |
2225 case InstArithmetic::Add: { | 2225 case InstArithmetic::Add: { |
2226 Variable *Src0LoR = SrcsLo.src0R(this); | 2226 Variable *Src0LoR = SrcsLo.src0R(this); |
2227 Operand *Src1LoRF = SrcsLo.src1RF(this); | 2227 Operand *Src1LoRF = SrcsLo.src1RF(this); |
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3429 return; | 3429 return; |
3430 case InstCast::Sext: { | 3430 case InstCast::Sext: { |
3431 if (isVectorType(Dest->getType())) { | 3431 if (isVectorType(Dest->getType())) { |
3432 Variable *T = makeReg(Dest->getType()); | 3432 Variable *T = makeReg(Dest->getType()); |
3433 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); | 3433 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); |
3434 _mov(Dest, T); | 3434 _mov(Dest, T); |
3435 UnimplementedError(Func->getContext()->getFlags()); | 3435 UnimplementedError(Func->getContext()->getFlags()); |
3436 } else if (Dest->getType() == IceType_i64) { | 3436 } else if (Dest->getType() == IceType_i64) { |
3437 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2 | 3437 // t1=sxtb src; t2= mov t1 asr #31; dst.lo=t1; dst.hi=t2 |
3438 Constant *ShiftAmt = Ctx->getConstantInt32(31); | 3438 Constant *ShiftAmt = Ctx->getConstantInt32(31); |
3439 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3439 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
3440 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3440 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
3441 Variable *T_Lo = makeReg(DestLo->getType()); | 3441 Variable *T_Lo = makeReg(DestLo->getType()); |
3442 if (Src0->getType() == IceType_i32) { | 3442 if (Src0->getType() == IceType_i32) { |
3443 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); | 3443 Operand *Src0RF = legalize(Src0, Legal_Reg | Legal_Flex); |
3444 _mov(T_Lo, Src0RF); | 3444 _mov(T_Lo, Src0RF); |
3445 } else if (Src0->getType() != IceType_i1) { | 3445 } else if (Src0->getType() != IceType_i1) { |
3446 Variable *Src0R = legalizeToReg(Src0); | 3446 Variable *Src0R = legalizeToReg(Src0); |
3447 _sxt(T_Lo, Src0R); | 3447 _sxt(T_Lo, Src0R); |
3448 } else { | 3448 } else { |
3449 Operand *_0 = Ctx->getConstantZero(IceType_i32); | 3449 Operand *_0 = Ctx->getConstantZero(IceType_i32); |
3450 Operand *_m1 = Ctx->getConstantInt32(-1); | 3450 Operand *_m1 = Ctx->getConstantInt32(-1); |
(...skipping 27 matching lines...) Expand all Loading... |
3478 case InstCast::Zext: { | 3478 case InstCast::Zext: { |
3479 if (isVectorType(Dest->getType())) { | 3479 if (isVectorType(Dest->getType())) { |
3480 Variable *T = makeReg(Dest->getType()); | 3480 Variable *T = makeReg(Dest->getType()); |
3481 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); | 3481 Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); |
3482 _mov(Dest, T); | 3482 _mov(Dest, T); |
3483 UnimplementedError(Func->getContext()->getFlags()); | 3483 UnimplementedError(Func->getContext()->getFlags()); |
3484 } else if (Dest->getType() == IceType_i64) { | 3484 } else if (Dest->getType() == IceType_i64) { |
3485 // t1=uxtb src; dst.lo=t1; dst.hi=0 | 3485 // t1=uxtb src; dst.lo=t1; dst.hi=0 |
3486 Operand *_0 = | 3486 Operand *_0 = |
3487 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); | 3487 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); |
3488 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 3488 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
3489 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3489 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
3490 Variable *T_Lo = makeReg(DestLo->getType()); | 3490 Variable *T_Lo = makeReg(DestLo->getType()); |
3491 | 3491 |
3492 switch (Src0->getType()) { | 3492 switch (Src0->getType()) { |
3493 default: { | 3493 default: { |
3494 assert(Src0->getType() != IceType_i64); | 3494 assert(Src0->getType() != IceType_i64); |
3495 _uxt(T_Lo, legalizeToReg(Src0)); | 3495 _uxt(T_Lo, legalizeToReg(Src0)); |
3496 } break; | 3496 } break; |
3497 case IceType_i32: { | 3497 case IceType_i32: { |
3498 _mov(T_Lo, legalize(Src0, Legal_Reg | Legal_Flex)); | 3498 _mov(T_Lo, legalize(Src0, Legal_Reg | Legal_Flex)); |
3499 } break; | 3499 } break; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3647 DestIsF32 | 3647 DestIsF32 |
3648 ? (SourceIsSigned ? InstARM32Vcvt::Si2s : InstARM32Vcvt::Ui2s) | 3648 ? (SourceIsSigned ? InstARM32Vcvt::Si2s : InstARM32Vcvt::Ui2s) |
3649 : (SourceIsSigned ? InstARM32Vcvt::Si2d : InstARM32Vcvt::Ui2d); | 3649 : (SourceIsSigned ? InstARM32Vcvt::Si2d : InstARM32Vcvt::Ui2d); |
3650 _vcvt(T, Src0R, Conversion); | 3650 _vcvt(T, Src0R, Conversion); |
3651 _mov(Dest, T); | 3651 _mov(Dest, T); |
3652 break; | 3652 break; |
3653 } | 3653 } |
3654 case InstCast::Bitcast: { | 3654 case InstCast::Bitcast: { |
3655 Operand *Src0 = Inst->getSrc(0); | 3655 Operand *Src0 = Inst->getSrc(0); |
3656 if (Dest->getType() == Src0->getType()) { | 3656 if (Dest->getType() == Src0->getType()) { |
3657 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); | 3657 auto *Assign = InstAssign::create(Func, Dest, Src0); |
3658 lowerAssign(Assign); | 3658 lowerAssign(Assign); |
3659 return; | 3659 return; |
3660 } | 3660 } |
3661 Type DestType = Dest->getType(); | 3661 Type DestType = Dest->getType(); |
3662 switch (DestType) { | 3662 switch (DestType) { |
3663 case IceType_NUM: | 3663 case IceType_NUM: |
3664 case IceType_void: | 3664 case IceType_void: |
3665 llvm::report_fatal_error("Unexpected bitcast."); | 3665 llvm::report_fatal_error("Unexpected bitcast."); |
3666 case IceType_i1: | 3666 case IceType_i1: |
3667 UnimplementedError(Func->getContext()->getFlags()); | 3667 UnimplementedError(Func->getContext()->getFlags()); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4021 Int32Operands Srcs(Src0, Src1); | 4021 Int32Operands Srcs(Src0, Src1); |
4022 const int32_t ShAmt = 32 - getScalarIntBitWidth(Src0->getType()); | 4022 const int32_t ShAmt = 32 - getScalarIntBitWidth(Src0->getType()); |
4023 assert(ShAmt >= 0); | 4023 assert(ShAmt >= 0); |
4024 | 4024 |
4025 if (!Srcs.hasConstOperand()) { | 4025 if (!Srcs.hasConstOperand()) { |
4026 Variable *Src0R = makeReg(IceType_i32); | 4026 Variable *Src0R = makeReg(IceType_i32); |
4027 Operand *ShAmtImm = shAmtImm(ShAmt); | 4027 Operand *ShAmtImm = shAmtImm(ShAmt); |
4028 _lsl(Src0R, legalizeToReg(Src0), ShAmtImm); | 4028 _lsl(Src0R, legalizeToReg(Src0), ShAmtImm); |
4029 | 4029 |
4030 Variable *Src1R = legalizeToReg(Src1); | 4030 Variable *Src1R = legalizeToReg(Src1); |
4031 OperandARM32FlexReg *Src1F = OperandARM32FlexReg::create( | 4031 auto *Src1F = OperandARM32FlexReg::create(Func, IceType_i32, Src1R, |
4032 Func, IceType_i32, Src1R, OperandARM32::LSL, ShAmtImm); | 4032 OperandARM32::LSL, ShAmtImm); |
4033 _cmp(Src0R, Src1F); | 4033 _cmp(Src0R, Src1F); |
4034 return CondWhenTrue(getIcmp32Mapping(Condition)); | 4034 return CondWhenTrue(getIcmp32Mapping(Condition)); |
4035 } | 4035 } |
4036 | 4036 |
4037 const int32_t Value = Srcs.getConstantValue(); | 4037 const int32_t Value = Srcs.getConstantValue(); |
4038 if ((Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) && Value == 0) { | 4038 if ((Condition == InstIcmp::Eq || Condition == InstIcmp::Ne) && Value == 0) { |
4039 Operand *ShAmtImm = shAmtImm(ShAmt); | 4039 Operand *ShAmtImm = shAmtImm(ShAmt); |
4040 Variable *T = makeReg(IceType_i32); | 4040 Variable *T = makeReg(IceType_i32); |
4041 _lsls(T, Srcs.src0R(this), ShAmtImm); | 4041 _lsls(T, Srcs.src0R(this), ShAmtImm); |
4042 Context.insert(InstFakeUse::create(Func, T)); | 4042 Context.insert(InstFakeUse::create(Func, T)); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4169 Variable *PtrContentsLoReg; | 4169 Variable *PtrContentsLoReg; |
4170 Variable *Value = Func->makeVariable(DestTy); | 4170 Variable *Value = Func->makeVariable(DestTy); |
4171 Variable *ValueReg; | 4171 Variable *ValueReg; |
4172 Variable *ValueHiReg; | 4172 Variable *ValueHiReg; |
4173 Variable *ValueLoReg; | 4173 Variable *ValueLoReg; |
4174 Variable *Success = makeReg(IceType_i32); | 4174 Variable *Success = makeReg(IceType_i32); |
4175 Variable *TmpReg; | 4175 Variable *TmpReg; |
4176 Variable *TmpHiReg; | 4176 Variable *TmpHiReg; |
4177 Variable *TmpLoReg; | 4177 Variable *TmpLoReg; |
4178 Operand *_0 = Ctx->getConstantZero(IceType_i32); | 4178 Operand *_0 = Ctx->getConstantZero(IceType_i32); |
4179 InstARM32Label *Retry = InstARM32Label::create(Func, this); | 4179 auto *Retry = InstARM32Label::create(Func, this); |
4180 | 4180 |
4181 if (DestTy == IceType_i64) { | 4181 if (DestTy == IceType_i64) { |
4182 Variable64On32 *PtrContentsReg64 = makeI64RegPair(); | 4182 Variable64On32 *PtrContentsReg64 = makeI64RegPair(); |
4183 PtrContentsHiReg = PtrContentsReg64->getHi(); | 4183 PtrContentsHiReg = PtrContentsReg64->getHi(); |
4184 PtrContentsLoReg = PtrContentsReg64->getLo(); | 4184 PtrContentsLoReg = PtrContentsReg64->getLo(); |
4185 PtrContentsReg = PtrContentsReg64; | 4185 PtrContentsReg = PtrContentsReg64; |
4186 | 4186 |
4187 llvm::cast<Variable64On32>(Value)->initHiLo(Func); | 4187 llvm::cast<Variable64On32>(Value)->initHiLo(Func); |
4188 Variable64On32 *ValueReg64 = makeI64RegPair(); | 4188 Variable64On32 *ValueReg64 = makeI64RegPair(); |
4189 ValueHiReg = ValueReg64->getHi(); | 4189 ValueHiReg = ValueReg64->getHi(); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4309 | 4309 |
4310 void TargetARM32::postambleCtpop64(const InstCall *Instr) { | 4310 void TargetARM32::postambleCtpop64(const InstCall *Instr) { |
4311 Operand *Arg0 = Instr->getArg(0); | 4311 Operand *Arg0 = Instr->getArg(0); |
4312 if (isInt32Asserting32Or64(Arg0->getType())) { | 4312 if (isInt32Asserting32Or64(Arg0->getType())) { |
4313 return; | 4313 return; |
4314 } | 4314 } |
4315 // The popcount helpers always return 32-bit values, while the intrinsic's | 4315 // The popcount helpers always return 32-bit values, while the intrinsic's |
4316 // signature matches some 64-bit platform's native instructions and expect to | 4316 // signature matches some 64-bit platform's native instructions and expect to |
4317 // fill a 64-bit reg. Thus, clear the upper bits of the dest just in case the | 4317 // fill a 64-bit reg. Thus, clear the upper bits of the dest just in case the |
4318 // user doesn't do that in the IR or doesn't toss the bits via truncate. | 4318 // user doesn't do that in the IR or doesn't toss the bits via truncate. |
4319 Variable *DestHi = llvm::cast<Variable>(hiOperand(Instr->getDest())); | 4319 auto *DestHi = llvm::cast<Variable>(hiOperand(Instr->getDest())); |
4320 Variable *T = makeReg(IceType_i32); | 4320 Variable *T = makeReg(IceType_i32); |
4321 Operand *_0 = | 4321 Operand *_0 = |
4322 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); | 4322 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); |
4323 _mov(T, _0); | 4323 _mov(T, _0); |
4324 _mov(DestHi, T); | 4324 _mov(DestHi, T); |
4325 } | 4325 } |
4326 | 4326 |
4327 void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { | 4327 void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
4328 Variable *Dest = Instr->getDest(); | 4328 Variable *Dest = Instr->getDest(); |
4329 Type DestTy = (Dest != nullptr) ? Dest->getType() : IceType_void; | 4329 Type DestTy = (Dest != nullptr) ? Dest->getType() : IceType_void; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4411 // | 4411 // |
4412 // The fake-use is needed to prevent those variables from being clobbered | 4412 // The fake-use is needed to prevent those variables from being clobbered |
4413 // in the loop (which will happen under register pressure.) | 4413 // in the loop (which will happen under register pressure.) |
4414 Variable64On32 *Tmp = makeI64RegPair(); | 4414 Variable64On32 *Tmp = makeI64RegPair(); |
4415 Variable64On32 *ValueVar = | 4415 Variable64On32 *ValueVar = |
4416 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); | 4416 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
4417 Variable *AddrVar = makeReg(IceType_i32); | 4417 Variable *AddrVar = makeReg(IceType_i32); |
4418 Variable *Success = makeReg(IceType_i32); | 4418 Variable *Success = makeReg(IceType_i32); |
4419 OperandARM32Mem *Mem; | 4419 OperandARM32Mem *Mem; |
4420 Operand *_0 = Ctx->getConstantZero(IceType_i32); | 4420 Operand *_0 = Ctx->getConstantZero(IceType_i32); |
4421 InstARM32Label *Retry = InstARM32Label::create(Func, this); | 4421 auto *Retry = InstARM32Label::create(Func, this); |
4422 Variable64On32 *NewReg = makeI64RegPair(); | 4422 Variable64On32 *NewReg = makeI64RegPair(); |
4423 ValueVar->initHiLo(Func); | 4423 ValueVar->initHiLo(Func); |
4424 ValueVar->mustNotHaveReg(); | 4424 ValueVar->mustNotHaveReg(); |
4425 | 4425 |
4426 _dmb(); | 4426 _dmb(); |
4427 lowerAssign(InstAssign::create(Func, ValueVar, Value)); | 4427 lowerAssign(InstAssign::create(Func, ValueVar, Value)); |
4428 lowerAssign(InstAssign::create(Func, AddrVar, Addr)); | 4428 lowerAssign(InstAssign::create(Func, AddrVar, Addr)); |
4429 | 4429 |
4430 Context.insert(Retry); | 4430 Context.insert(Retry); |
4431 Context.insert(InstFakeDef::create(Func, NewReg)); | 4431 Context.insert(InstFakeDef::create(Func, NewReg)); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4502 Func->setError("Unexpected memory ordering for AtomicCmpxchg"); | 4502 Func->setError("Unexpected memory ordering for AtomicCmpxchg"); |
4503 return; | 4503 return; |
4504 } | 4504 } |
4505 | 4505 |
4506 OperandARM32Mem *Mem; | 4506 OperandARM32Mem *Mem; |
4507 Variable *TmpReg; | 4507 Variable *TmpReg; |
4508 Variable *Expected, *ExpectedReg; | 4508 Variable *Expected, *ExpectedReg; |
4509 Variable *New, *NewReg; | 4509 Variable *New, *NewReg; |
4510 Variable *Success = makeReg(IceType_i32); | 4510 Variable *Success = makeReg(IceType_i32); |
4511 Operand *_0 = Ctx->getConstantZero(IceType_i32); | 4511 Operand *_0 = Ctx->getConstantZero(IceType_i32); |
4512 InstARM32Label *Retry = InstARM32Label::create(Func, this); | 4512 auto *Retry = InstARM32Label::create(Func, this); |
4513 | 4513 |
4514 if (DestTy == IceType_i64) { | 4514 if (DestTy == IceType_i64) { |
4515 Variable64On32 *TmpReg64 = makeI64RegPair(); | 4515 Variable64On32 *TmpReg64 = makeI64RegPair(); |
4516 Variable64On32 *New64 = | 4516 Variable64On32 *New64 = |
4517 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); | 4517 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
4518 Variable64On32 *NewReg64 = makeI64RegPair(); | 4518 Variable64On32 *NewReg64 = makeI64RegPair(); |
4519 Variable64On32 *Expected64 = | 4519 Variable64On32 *Expected64 = |
4520 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); | 4520 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
4521 Variable64On32 *ExpectedReg64 = makeI64RegPair(); | 4521 Variable64On32 *ExpectedReg64 = makeI64RegPair(); |
4522 | 4522 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4613 } | 4613 } |
4614 case Intrinsics::Bswap: { | 4614 case Intrinsics::Bswap: { |
4615 Operand *Val = Instr->getArg(0); | 4615 Operand *Val = Instr->getArg(0); |
4616 Type Ty = Val->getType(); | 4616 Type Ty = Val->getType(); |
4617 if (Ty == IceType_i64) { | 4617 if (Ty == IceType_i64) { |
4618 Val = legalizeUndef(Val); | 4618 Val = legalizeUndef(Val); |
4619 Variable *Val_Lo = legalizeToReg(loOperand(Val)); | 4619 Variable *Val_Lo = legalizeToReg(loOperand(Val)); |
4620 Variable *Val_Hi = legalizeToReg(hiOperand(Val)); | 4620 Variable *Val_Hi = legalizeToReg(hiOperand(Val)); |
4621 Variable *T_Lo = makeReg(IceType_i32); | 4621 Variable *T_Lo = makeReg(IceType_i32); |
4622 Variable *T_Hi = makeReg(IceType_i32); | 4622 Variable *T_Hi = makeReg(IceType_i32); |
4623 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 4623 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
4624 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 4624 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
4625 _rev(T_Lo, Val_Lo); | 4625 _rev(T_Lo, Val_Lo); |
4626 _rev(T_Hi, Val_Hi); | 4626 _rev(T_Hi, Val_Hi); |
4627 _mov(DestLo, T_Hi); | 4627 _mov(DestLo, T_Hi); |
4628 _mov(DestHi, T_Lo); | 4628 _mov(DestHi, T_Lo); |
4629 } else { | 4629 } else { |
4630 assert(Ty == IceType_i32 || Ty == IceType_i16); | 4630 assert(Ty == IceType_i32 || Ty == IceType_i16); |
4631 Variable *ValR = legalizeToReg(Val); | 4631 Variable *ValR = legalizeToReg(Val); |
4632 Variable *T = makeReg(Ty); | 4632 Variable *T = makeReg(Ty); |
4633 _rev(T, ValR); | 4633 _rev(T, ValR); |
4634 if (Val->getType() == IceType_i16) { | 4634 if (Val->getType() == IceType_i16) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4747 } | 4747 } |
4748 return; | 4748 return; |
4749 } | 4749 } |
4750 | 4750 |
4751 void TargetARM32::lowerCLZ(Variable *Dest, Variable *ValLoR, Variable *ValHiR) { | 4751 void TargetARM32::lowerCLZ(Variable *Dest, Variable *ValLoR, Variable *ValHiR) { |
4752 Type Ty = Dest->getType(); | 4752 Type Ty = Dest->getType(); |
4753 assert(Ty == IceType_i32 || Ty == IceType_i64); | 4753 assert(Ty == IceType_i32 || Ty == IceType_i64); |
4754 Variable *T = makeReg(IceType_i32); | 4754 Variable *T = makeReg(IceType_i32); |
4755 _clz(T, ValLoR); | 4755 _clz(T, ValLoR); |
4756 if (Ty == IceType_i64) { | 4756 if (Ty == IceType_i64) { |
4757 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 4757 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
4758 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 4758 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
4759 Operand *Zero = | 4759 Operand *Zero = |
4760 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); | 4760 legalize(Ctx->getConstantZero(IceType_i32), Legal_Reg | Legal_Flex); |
4761 Operand *ThirtyTwo = | 4761 Operand *ThirtyTwo = |
4762 legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex); | 4762 legalize(Ctx->getConstantInt32(32), Legal_Reg | Legal_Flex); |
4763 _cmp(ValHiR, Zero); | 4763 _cmp(ValHiR, Zero); |
4764 Variable *T2 = makeReg(IceType_i32); | 4764 Variable *T2 = makeReg(IceType_i32); |
4765 _add(T2, T, ThirtyTwo); | 4765 _add(T2, T, ThirtyTwo); |
4766 _clz(T2, ValHiR, CondARM32::NE); | 4766 _clz(T2, ValHiR, CondARM32::NE); |
4767 // T2 is actually a source as well when the predicate is not AL (since it | 4767 // T2 is actually a source as well when the predicate is not AL (since it |
4768 // may leave T2 alone). We use _set_dest_redefined to prolong the liveness | 4768 // may leave T2 alone). We use _set_dest_redefined to prolong the liveness |
(...skipping 11 matching lines...) Expand all Loading... |
4780 | 4780 |
4781 void TargetARM32::lowerLoad(const InstLoad *Load) { | 4781 void TargetARM32::lowerLoad(const InstLoad *Load) { |
4782 // A Load instruction can be treated the same as an Assign instruction, after | 4782 // A Load instruction can be treated the same as an Assign instruction, after |
4783 // the source operand is transformed into an OperandARM32Mem operand. | 4783 // the source operand is transformed into an OperandARM32Mem operand. |
4784 Type Ty = Load->getDest()->getType(); | 4784 Type Ty = Load->getDest()->getType(); |
4785 Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty); | 4785 Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty); |
4786 Variable *DestLoad = Load->getDest(); | 4786 Variable *DestLoad = Load->getDest(); |
4787 | 4787 |
4788 // TODO(jvoung): handled folding opportunities. Sign and zero extension can | 4788 // TODO(jvoung): handled folding opportunities. Sign and zero extension can |
4789 // be folded into a load. | 4789 // be folded into a load. |
4790 InstAssign *Assign = InstAssign::create(Func, DestLoad, Src0); | 4790 auto *Assign = InstAssign::create(Func, DestLoad, Src0); |
4791 lowerAssign(Assign); | 4791 lowerAssign(Assign); |
4792 } | 4792 } |
4793 | 4793 |
4794 namespace { | 4794 namespace { |
4795 void dumpAddressOpt(const Cfg *Func, const Variable *Base, int32_t Offset, | 4795 void dumpAddressOpt(const Cfg *Func, const Variable *Base, int32_t Offset, |
4796 const Variable *OffsetReg, int16_t OffsetRegShAmt, | 4796 const Variable *OffsetReg, int16_t OffsetRegShAmt, |
4797 const Inst *Reason) { | 4797 const Inst *Reason) { |
4798 if (!BuildDefs::dump()) | 4798 if (!BuildDefs::dump()) |
4799 return; | 4799 return; |
4800 if (!Func->isVerbose(IceV_AddrOpt)) | 4800 if (!Func->isVerbose(IceV_AddrOpt)) |
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5617 // being lowered is a 64 bit value, then the result should be split and the | 5617 // being lowered is a 64 bit value, then the result should be split and the |
5618 // lo and hi components will need to go in uninitialized registers. | 5618 // lo and hi components will need to go in uninitialized registers. |
5619 if (isVectorType(Ty)) | 5619 if (isVectorType(Ty)) |
5620 return makeVectorOfZeros(Ty, RegNum); | 5620 return makeVectorOfZeros(Ty, RegNum); |
5621 return Ctx->getConstantZero(Ty); | 5621 return Ctx->getConstantZero(Ty); |
5622 } | 5622 } |
5623 return From; | 5623 return From; |
5624 } | 5624 } |
5625 | 5625 |
5626 OperandARM32Mem *TargetARM32::formMemoryOperand(Operand *Operand, Type Ty) { | 5626 OperandARM32Mem *TargetARM32::formMemoryOperand(Operand *Operand, Type Ty) { |
5627 OperandARM32Mem *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand); | 5627 auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Operand); |
5628 // It may be the case that address mode optimization already creates an | 5628 // It may be the case that address mode optimization already creates an |
5629 // OperandARM32Mem, so in that case it wouldn't need another level of | 5629 // OperandARM32Mem, so in that case it wouldn't need another level of |
5630 // transformation. | 5630 // transformation. |
5631 if (Mem) { | 5631 if (Mem) { |
5632 return llvm::cast<OperandARM32Mem>(legalize(Mem)); | 5632 return llvm::cast<OperandARM32Mem>(legalize(Mem)); |
5633 } | 5633 } |
5634 // If we didn't do address mode optimization, then we only have a | 5634 // If we didn't do address mode optimization, then we only have a |
5635 // base/offset to work with. ARM always requires a base register, so | 5635 // base/offset to work with. ARM always requires a base register, so |
5636 // just use that to hold the operand. | 5636 // just use that to hold the operand. |
5637 Variable *Base = llvm::cast<Variable>( | 5637 auto *Base = llvm::cast<Variable>( |
5638 legalize(Operand, Legal_Reg | Legal_Rematerializable)); | 5638 legalize(Operand, Legal_Reg | Legal_Rematerializable)); |
5639 return OperandARM32Mem::create( | 5639 return OperandARM32Mem::create( |
5640 Func, Ty, Base, | 5640 Func, Ty, Base, |
5641 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); | 5641 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); |
5642 } | 5642 } |
5643 | 5643 |
5644 Variable64On32 *TargetARM32::makeI64RegPair() { | 5644 Variable64On32 *TargetARM32::makeI64RegPair() { |
5645 Variable64On32 *Reg = | 5645 Variable64On32 *Reg = |
5646 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); | 5646 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
5647 Reg->setMustHaveReg(); | 5647 Reg->setMustHaveReg(); |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6433 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 6433 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
6434 // However, for compatibility with current NaCl LLVM, don't claim that. | 6434 // However, for compatibility with current NaCl LLVM, don't claim that. |
6435 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6435 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6436 } | 6436 } |
6437 | 6437 |
6438 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; | 6438 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; |
6439 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6439 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6440 llvm::SmallBitVector TargetARM32::ScratchRegs; | 6440 llvm::SmallBitVector TargetARM32::ScratchRegs; |
6441 | 6441 |
6442 } // end of namespace Ice | 6442 } // end of namespace Ice |
OLD | NEW |