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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 I64PairRegisters[RegARM32::val] = isI64Pair; \ | 176 I64PairRegisters[RegARM32::val] = isI64Pair; \ |
177 Float32Registers[RegARM32::val] = isFP32; \ | 177 Float32Registers[RegARM32::val] = isFP32; \ |
178 Float64Registers[RegARM32::val] = isFP64; \ | 178 Float64Registers[RegARM32::val] = isFP64; \ |
179 VectorRegisters[RegARM32::val] = isVec128; \ | 179 VectorRegisters[RegARM32::val] = isVec128; \ |
180 RegisterAliases[RegARM32::val].resize(RegARM32::Reg_NUM); \ | 180 RegisterAliases[RegARM32::val].resize(RegARM32::Reg_NUM); \ |
181 for (SizeT RegAlias : alias_init) { \ | 181 for (SizeT RegAlias : alias_init) { \ |
182 assert(!RegisterAliases[RegARM32::val][RegAlias] && \ | 182 assert(!RegisterAliases[RegARM32::val][RegAlias] && \ |
183 "Duplicate alias for " #val); \ | 183 "Duplicate alias for " #val); \ |
184 RegisterAliases[RegARM32::val].set(RegAlias); \ | 184 RegisterAliases[RegARM32::val].set(RegAlias); \ |
185 } \ | 185 } \ |
186 assert(RegisterAliases[RegARM32::val][RegARM32::val]); \ | 186 RegisterAliases[RegARM32::val].set(RegARM32::val); \ |
187 ScratchRegs[RegARM32::val] = scratch; | 187 ScratchRegs[RegARM32::val] = scratch; |
188 REGARM32_TABLE; | 188 REGARM32_TABLE; |
189 #undef X | 189 #undef X |
190 TypeToRegisterSet[IceType_void] = InvalidRegisters; | 190 TypeToRegisterSet[IceType_void] = InvalidRegisters; |
191 TypeToRegisterSet[IceType_i1] = IntegerRegisters; | 191 TypeToRegisterSet[IceType_i1] = IntegerRegisters; |
192 TypeToRegisterSet[IceType_i8] = IntegerRegisters; | 192 TypeToRegisterSet[IceType_i8] = IntegerRegisters; |
193 TypeToRegisterSet[IceType_i16] = IntegerRegisters; | 193 TypeToRegisterSet[IceType_i16] = IntegerRegisters; |
194 TypeToRegisterSet[IceType_i32] = IntegerRegisters; | 194 TypeToRegisterSet[IceType_i32] = IntegerRegisters; |
195 TypeToRegisterSet[IceType_i64] = I64PairRegisters; | 195 TypeToRegisterSet[IceType_i64] = I64PairRegisters; |
196 TypeToRegisterSet[IceType_f32] = Float32Registers; | 196 TypeToRegisterSet[IceType_f32] = Float32Registers; |
(...skipping 2374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2571 return; | 2571 return; |
2572 } | 2572 } |
2573 | 2573 |
2574 void TargetARM32::lowerInsertElement(const InstInsertElement *Inst) { | 2574 void TargetARM32::lowerInsertElement(const InstInsertElement *Inst) { |
2575 (void)Inst; | 2575 (void)Inst; |
2576 UnimplementedError(Func->getContext()->getFlags()); | 2576 UnimplementedError(Func->getContext()->getFlags()); |
2577 } | 2577 } |
2578 | 2578 |
2579 namespace { | 2579 namespace { |
2580 inline uint64_t getConstantMemoryOrder(Operand *Opnd) { | 2580 inline uint64_t getConstantMemoryOrder(Operand *Opnd) { |
2581 if (auto Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) | 2581 if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) |
2582 return Integer->getValue(); | 2582 return Integer->getValue(); |
2583 return Intrinsics::MemoryOrderInvalid; | 2583 return Intrinsics::MemoryOrderInvalid; |
2584 } | 2584 } |
2585 } // end of anonymous namespace | 2585 } // end of anonymous namespace |
2586 | 2586 |
2587 void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation, | 2587 void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation, |
2588 Operand *Ptr, Operand *Val) { | 2588 Operand *Ptr, Operand *Val) { |
2589 // retry: | 2589 // retry: |
2590 // ldrex contents, [addr] | 2590 // ldrex contents, [addr] |
2591 // op tmp, contents, operand | 2591 // op tmp, contents, operand |
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3474 int32_t RegNum) { | 3474 int32_t RegNum) { |
3475 Type Ty = From->getType(); | 3475 Type Ty = From->getType(); |
3476 // Assert that a physical register is allowed. To date, all calls to | 3476 // Assert that a physical register is allowed. To date, all calls to |
3477 // legalize() allow a physical register. Legal_Flex converts registers to the | 3477 // legalize() allow a physical register. Legal_Flex converts registers to the |
3478 // right type OperandARM32FlexReg as needed. | 3478 // right type OperandARM32FlexReg as needed. |
3479 assert(Allowed & Legal_Reg); | 3479 assert(Allowed & Legal_Reg); |
3480 // Go through the various types of operands: OperandARM32Mem, | 3480 // Go through the various types of operands: OperandARM32Mem, |
3481 // OperandARM32Flex, Constant, and Variable. Given the above assertion, if | 3481 // OperandARM32Flex, Constant, and Variable. Given the above assertion, if |
3482 // type of operand is not legal (e.g., OperandARM32Mem and !Legal_Mem), we | 3482 // type of operand is not legal (e.g., OperandARM32Mem and !Legal_Mem), we |
3483 // can always copy to a register. | 3483 // can always copy to a register. |
3484 if (auto Mem = llvm::dyn_cast<OperandARM32Mem>(From)) { | 3484 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(From)) { |
3485 static const struct { | 3485 static const struct { |
3486 bool CanHaveOffset; | 3486 bool CanHaveOffset; |
3487 bool CanHaveIndex; | 3487 bool CanHaveIndex; |
3488 } MemTraits[] = { | 3488 } MemTraits[] = { |
3489 #define X(tag, elementty, int_width, vec_width, sbits, ubits, rraddr) \ | 3489 #define X(tag, elementty, int_width, vec_width, sbits, ubits, rraddr) \ |
3490 { (ubits) > 0, rraddr } \ | 3490 { (ubits) > 0, rraddr } \ |
3491 , | 3491 , |
3492 ICETYPEARM32_TABLE | 3492 ICETYPEARM32_TABLE |
3493 #undef X | 3493 #undef X |
3494 }; | 3494 }; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3539 if (Allowed & Legal_Mem) { | 3539 if (Allowed & Legal_Mem) { |
3540 From = Mem; | 3540 From = Mem; |
3541 } else { | 3541 } else { |
3542 Variable *Reg = makeReg(Ty, RegNum); | 3542 Variable *Reg = makeReg(Ty, RegNum); |
3543 _ldr(Reg, Mem); | 3543 _ldr(Reg, Mem); |
3544 From = Reg; | 3544 From = Reg; |
3545 } | 3545 } |
3546 return From; | 3546 return From; |
3547 } | 3547 } |
3548 | 3548 |
3549 if (auto Flex = llvm::dyn_cast<OperandARM32Flex>(From)) { | 3549 if (auto *Flex = llvm::dyn_cast<OperandARM32Flex>(From)) { |
3550 if (!(Allowed & Legal_Flex)) { | 3550 if (!(Allowed & Legal_Flex)) { |
3551 if (auto FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Flex)) { | 3551 if (auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Flex)) { |
3552 if (FlexReg->getShiftOp() == OperandARM32::kNoShift) { | 3552 if (FlexReg->getShiftOp() == OperandARM32::kNoShift) { |
3553 From = FlexReg->getReg(); | 3553 From = FlexReg->getReg(); |
3554 // Fall through and let From be checked as a Variable below, where it | 3554 // Fall through and let From be checked as a Variable below, where it |
3555 // may or may not need a register. | 3555 // may or may not need a register. |
3556 } else { | 3556 } else { |
3557 return copyToReg(Flex, RegNum); | 3557 return copyToReg(Flex, RegNum); |
3558 } | 3558 } |
3559 } else { | 3559 } else { |
3560 return copyToReg(Flex, RegNum); | 3560 return copyToReg(Flex, RegNum); |
3561 } | 3561 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3622 llvm::cast<Constant>(From)->setShouldBePooled(true); | 3622 llvm::cast<Constant>(From)->setShouldBePooled(true); |
3623 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); | 3623 Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true); |
3624 Variable *BaseReg = makeReg(getPointerType()); | 3624 Variable *BaseReg = makeReg(getPointerType()); |
3625 _movw(BaseReg, Offset); | 3625 _movw(BaseReg, Offset); |
3626 _movt(BaseReg, Offset); | 3626 _movt(BaseReg, Offset); |
3627 From = formMemoryOperand(BaseReg, Ty); | 3627 From = formMemoryOperand(BaseReg, Ty); |
3628 return copyToReg(From, RegNum); | 3628 return copyToReg(From, RegNum); |
3629 } | 3629 } |
3630 } | 3630 } |
3631 | 3631 |
3632 if (auto Var = llvm::dyn_cast<Variable>(From)) { | 3632 if (auto *Var = llvm::dyn_cast<Variable>(From)) { |
3633 // Check if the variable is guaranteed a physical register. This can happen | 3633 // Check if the variable is guaranteed a physical register. This can happen |
3634 // either when the variable is pre-colored or when it is assigned infinite | 3634 // either when the variable is pre-colored or when it is assigned infinite |
3635 // weight. | 3635 // weight. |
3636 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); | 3636 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
3637 // We need a new physical register for the operand if: | 3637 // We need a new physical register for the operand if: |
3638 // Mem is not allowed and Var isn't guaranteed a physical | 3638 // Mem is not allowed and Var isn't guaranteed a physical |
3639 // register, or | 3639 // register, or |
3640 // RegNum is required and Var->getRegNum() doesn't match. | 3640 // RegNum is required and Var->getRegNum() doesn't match. |
3641 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 3641 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
3642 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 3642 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3954 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; | 3954 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; |
3955 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 3955 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { |
3956 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; | 3956 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; |
3957 } | 3957 } |
3958 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 3958 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
3959 // However, for compatibility with current NaCl LLVM, don't claim that. | 3959 // However, for compatibility with current NaCl LLVM, don't claim that. |
3960 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 3960 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
3961 } | 3961 } |
3962 | 3962 |
3963 } // end of namespace Ice | 3963 } // end of namespace Ice |
OLD | NEW |