xref: /aosp_15_r20/external/llvm/lib/Target/AArch64/AArch64Subtarget.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--- AArch64Subtarget.h - Define Subtarget for the AArch64 -*- C++ -*--===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file declares the AArch64 specific subclass of TargetSubtarget.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_AARCH64_AARCH64SUBTARGET_H
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "AArch64FrameLowering.h"
18*9880d681SAndroid Build Coastguard Worker #include "AArch64ISelLowering.h"
19*9880d681SAndroid Build Coastguard Worker #include "AArch64InstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "AArch64RegisterInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "AArch64SelectionDAGInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/GlobalISel/GISelAccessor.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include <string>
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker #define GET_SUBTARGETINFO_HEADER
28*9880d681SAndroid Build Coastguard Worker #include "AArch64GenSubtargetInfo.inc"
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker namespace llvm {
31*9880d681SAndroid Build Coastguard Worker class GlobalValue;
32*9880d681SAndroid Build Coastguard Worker class StringRef;
33*9880d681SAndroid Build Coastguard Worker class Triple;
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker class AArch64Subtarget : public AArch64GenSubtargetInfo {
36*9880d681SAndroid Build Coastguard Worker public:
37*9880d681SAndroid Build Coastguard Worker   enum ARMProcFamilyEnum : uint8_t {
38*9880d681SAndroid Build Coastguard Worker     Others,
39*9880d681SAndroid Build Coastguard Worker     CortexA35,
40*9880d681SAndroid Build Coastguard Worker     CortexA53,
41*9880d681SAndroid Build Coastguard Worker     CortexA57,
42*9880d681SAndroid Build Coastguard Worker     CortexA72,
43*9880d681SAndroid Build Coastguard Worker     CortexA73,
44*9880d681SAndroid Build Coastguard Worker     Cyclone,
45*9880d681SAndroid Build Coastguard Worker     ExynosM1,
46*9880d681SAndroid Build Coastguard Worker     Kryo,
47*9880d681SAndroid Build Coastguard Worker     Vulcan
48*9880d681SAndroid Build Coastguard Worker   };
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker protected:
51*9880d681SAndroid Build Coastguard Worker   /// ARMProcFamily - ARM processor family: Cortex-A53, Cortex-A57, and others.
52*9880d681SAndroid Build Coastguard Worker   ARMProcFamilyEnum ARMProcFamily = Others;
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker   bool HasV8_1aOps = false;
55*9880d681SAndroid Build Coastguard Worker   bool HasV8_2aOps = false;
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker   bool HasFPARMv8 = false;
58*9880d681SAndroid Build Coastguard Worker   bool HasNEON = false;
59*9880d681SAndroid Build Coastguard Worker   bool HasCrypto = false;
60*9880d681SAndroid Build Coastguard Worker   bool HasCRC = false;
61*9880d681SAndroid Build Coastguard Worker   bool HasRAS = false;
62*9880d681SAndroid Build Coastguard Worker   bool HasPerfMon = false;
63*9880d681SAndroid Build Coastguard Worker   bool HasFullFP16 = false;
64*9880d681SAndroid Build Coastguard Worker   bool HasSPE = false;
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker   // HasZeroCycleRegMove - Has zero-cycle register mov instructions.
67*9880d681SAndroid Build Coastguard Worker   bool HasZeroCycleRegMove = false;
68*9880d681SAndroid Build Coastguard Worker 
69*9880d681SAndroid Build Coastguard Worker   // HasZeroCycleZeroing - Has zero-cycle zeroing instructions.
70*9880d681SAndroid Build Coastguard Worker   bool HasZeroCycleZeroing = false;
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker   // StrictAlign - Disallow unaligned memory accesses.
73*9880d681SAndroid Build Coastguard Worker   bool StrictAlign = false;
74*9880d681SAndroid Build Coastguard Worker   bool MergeNarrowLoads = false;
75*9880d681SAndroid Build Coastguard Worker   bool UseAA = false;
76*9880d681SAndroid Build Coastguard Worker   bool PredictableSelectIsExpensive = false;
77*9880d681SAndroid Build Coastguard Worker   bool BalanceFPOps = false;
78*9880d681SAndroid Build Coastguard Worker   bool CustomAsCheapAsMove = false;
79*9880d681SAndroid Build Coastguard Worker   bool UsePostRAScheduler = false;
80*9880d681SAndroid Build Coastguard Worker   bool Misaligned128StoreIsSlow = false;
81*9880d681SAndroid Build Coastguard Worker   bool AvoidQuadLdStPairs = false;
82*9880d681SAndroid Build Coastguard Worker   bool UseAlternateSExtLoadCVTF32Pattern = false;
83*9880d681SAndroid Build Coastguard Worker   bool HasMacroOpFusion = false;
84*9880d681SAndroid Build Coastguard Worker   bool DisableLatencySchedHeuristic = false;
85*9880d681SAndroid Build Coastguard Worker   bool UseRSqrt = false;
86*9880d681SAndroid Build Coastguard Worker   uint8_t MaxInterleaveFactor = 2;
87*9880d681SAndroid Build Coastguard Worker   uint8_t VectorInsertExtractBaseCost = 3;
88*9880d681SAndroid Build Coastguard Worker   uint16_t CacheLineSize = 0;
89*9880d681SAndroid Build Coastguard Worker   uint16_t PrefetchDistance = 0;
90*9880d681SAndroid Build Coastguard Worker   uint16_t MinPrefetchStride = 1;
91*9880d681SAndroid Build Coastguard Worker   unsigned MaxPrefetchIterationsAhead = UINT_MAX;
92*9880d681SAndroid Build Coastguard Worker   unsigned PrefFunctionAlignment = 0;
93*9880d681SAndroid Build Coastguard Worker   unsigned PrefLoopAlignment = 0;
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   // ReserveX18 - X18 is not available as a general purpose register.
96*9880d681SAndroid Build Coastguard Worker   bool ReserveX18;
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   bool IsLittle;
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   /// CPUString - String name of used CPU.
101*9880d681SAndroid Build Coastguard Worker   std::string CPUString;
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker   /// TargetTriple - What processor and OS we're targeting.
104*9880d681SAndroid Build Coastguard Worker   Triple TargetTriple;
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker   AArch64FrameLowering FrameLowering;
107*9880d681SAndroid Build Coastguard Worker   AArch64InstrInfo InstrInfo;
108*9880d681SAndroid Build Coastguard Worker   AArch64SelectionDAGInfo TSInfo;
109*9880d681SAndroid Build Coastguard Worker   AArch64TargetLowering TLInfo;
110*9880d681SAndroid Build Coastguard Worker   /// Gather the accessor points to GlobalISel-related APIs.
111*9880d681SAndroid Build Coastguard Worker   /// This is used to avoid ifndefs spreading around while GISel is
112*9880d681SAndroid Build Coastguard Worker   /// an optional library.
113*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<GISelAccessor> GISel;
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker private:
116*9880d681SAndroid Build Coastguard Worker   /// initializeSubtargetDependencies - Initializes using CPUString and the
117*9880d681SAndroid Build Coastguard Worker   /// passed in feature string so that we can use initializer lists for
118*9880d681SAndroid Build Coastguard Worker   /// subtarget initialization.
119*9880d681SAndroid Build Coastguard Worker   AArch64Subtarget &initializeSubtargetDependencies(StringRef FS);
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   /// Initialize properties based on the selected processor family.
122*9880d681SAndroid Build Coastguard Worker   void initializeProperties();
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker public:
125*9880d681SAndroid Build Coastguard Worker   /// This constructor initializes the data members to match that
126*9880d681SAndroid Build Coastguard Worker   /// of the specified triple.
127*9880d681SAndroid Build Coastguard Worker   AArch64Subtarget(const Triple &TT, const std::string &CPU,
128*9880d681SAndroid Build Coastguard Worker                    const std::string &FS, const TargetMachine &TM,
129*9880d681SAndroid Build Coastguard Worker                    bool LittleEndian);
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   /// This object will take onwership of \p GISelAccessor.
setGISelAccessor(GISelAccessor & GISel)132*9880d681SAndroid Build Coastguard Worker   void setGISelAccessor(GISelAccessor &GISel) {
133*9880d681SAndroid Build Coastguard Worker     this->GISel.reset(&GISel);
134*9880d681SAndroid Build Coastguard Worker   }
135*9880d681SAndroid Build Coastguard Worker 
getSelectionDAGInfo()136*9880d681SAndroid Build Coastguard Worker   const AArch64SelectionDAGInfo *getSelectionDAGInfo() const override {
137*9880d681SAndroid Build Coastguard Worker     return &TSInfo;
138*9880d681SAndroid Build Coastguard Worker   }
getFrameLowering()139*9880d681SAndroid Build Coastguard Worker   const AArch64FrameLowering *getFrameLowering() const override {
140*9880d681SAndroid Build Coastguard Worker     return &FrameLowering;
141*9880d681SAndroid Build Coastguard Worker   }
getTargetLowering()142*9880d681SAndroid Build Coastguard Worker   const AArch64TargetLowering *getTargetLowering() const override {
143*9880d681SAndroid Build Coastguard Worker     return &TLInfo;
144*9880d681SAndroid Build Coastguard Worker   }
getInstrInfo()145*9880d681SAndroid Build Coastguard Worker   const AArch64InstrInfo *getInstrInfo() const override { return &InstrInfo; }
getRegisterInfo()146*9880d681SAndroid Build Coastguard Worker   const AArch64RegisterInfo *getRegisterInfo() const override {
147*9880d681SAndroid Build Coastguard Worker     return &getInstrInfo()->getRegisterInfo();
148*9880d681SAndroid Build Coastguard Worker   }
149*9880d681SAndroid Build Coastguard Worker   const CallLowering *getCallLowering() const override;
150*9880d681SAndroid Build Coastguard Worker   const RegisterBankInfo *getRegBankInfo() const override;
getTargetTriple()151*9880d681SAndroid Build Coastguard Worker   const Triple &getTargetTriple() const { return TargetTriple; }
enableMachineScheduler()152*9880d681SAndroid Build Coastguard Worker   bool enableMachineScheduler() const override { return true; }
enablePostRAScheduler()153*9880d681SAndroid Build Coastguard Worker   bool enablePostRAScheduler() const override {
154*9880d681SAndroid Build Coastguard Worker     return UsePostRAScheduler;
155*9880d681SAndroid Build Coastguard Worker   }
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker   /// Returns ARM processor family.
158*9880d681SAndroid Build Coastguard Worker   /// Avoid this function! CPU specifics should be kept local to this class
159*9880d681SAndroid Build Coastguard Worker   /// and preferably modeled with SubtargetFeatures or properties in
160*9880d681SAndroid Build Coastguard Worker   /// initializeProperties().
getProcFamily()161*9880d681SAndroid Build Coastguard Worker   ARMProcFamilyEnum getProcFamily() const {
162*9880d681SAndroid Build Coastguard Worker     return ARMProcFamily;
163*9880d681SAndroid Build Coastguard Worker   }
164*9880d681SAndroid Build Coastguard Worker 
hasV8_1aOps()165*9880d681SAndroid Build Coastguard Worker   bool hasV8_1aOps() const { return HasV8_1aOps; }
hasV8_2aOps()166*9880d681SAndroid Build Coastguard Worker   bool hasV8_2aOps() const { return HasV8_2aOps; }
167*9880d681SAndroid Build Coastguard Worker 
hasZeroCycleRegMove()168*9880d681SAndroid Build Coastguard Worker   bool hasZeroCycleRegMove() const { return HasZeroCycleRegMove; }
169*9880d681SAndroid Build Coastguard Worker 
hasZeroCycleZeroing()170*9880d681SAndroid Build Coastguard Worker   bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; }
171*9880d681SAndroid Build Coastguard Worker 
requiresStrictAlign()172*9880d681SAndroid Build Coastguard Worker   bool requiresStrictAlign() const { return StrictAlign; }
173*9880d681SAndroid Build Coastguard Worker 
isX18Reserved()174*9880d681SAndroid Build Coastguard Worker   bool isX18Reserved() const { return ReserveX18; }
hasFPARMv8()175*9880d681SAndroid Build Coastguard Worker   bool hasFPARMv8() const { return HasFPARMv8; }
hasNEON()176*9880d681SAndroid Build Coastguard Worker   bool hasNEON() const { return HasNEON; }
hasCrypto()177*9880d681SAndroid Build Coastguard Worker   bool hasCrypto() const { return HasCrypto; }
hasCRC()178*9880d681SAndroid Build Coastguard Worker   bool hasCRC() const { return HasCRC; }
hasRAS()179*9880d681SAndroid Build Coastguard Worker   bool hasRAS() const { return HasRAS; }
mergeNarrowLoads()180*9880d681SAndroid Build Coastguard Worker   bool mergeNarrowLoads() const { return MergeNarrowLoads; }
balanceFPOps()181*9880d681SAndroid Build Coastguard Worker   bool balanceFPOps() const { return BalanceFPOps; }
predictableSelectIsExpensive()182*9880d681SAndroid Build Coastguard Worker   bool predictableSelectIsExpensive() const {
183*9880d681SAndroid Build Coastguard Worker     return PredictableSelectIsExpensive;
184*9880d681SAndroid Build Coastguard Worker   }
hasCustomCheapAsMoveHandling()185*9880d681SAndroid Build Coastguard Worker   bool hasCustomCheapAsMoveHandling() const { return CustomAsCheapAsMove; }
isMisaligned128StoreSlow()186*9880d681SAndroid Build Coastguard Worker   bool isMisaligned128StoreSlow() const { return Misaligned128StoreIsSlow; }
avoidQuadLdStPairs()187*9880d681SAndroid Build Coastguard Worker   bool avoidQuadLdStPairs() const { return AvoidQuadLdStPairs; }
useAlternateSExtLoadCVTF32Pattern()188*9880d681SAndroid Build Coastguard Worker   bool useAlternateSExtLoadCVTF32Pattern() const {
189*9880d681SAndroid Build Coastguard Worker     return UseAlternateSExtLoadCVTF32Pattern;
190*9880d681SAndroid Build Coastguard Worker   }
hasMacroOpFusion()191*9880d681SAndroid Build Coastguard Worker   bool hasMacroOpFusion() const { return HasMacroOpFusion; }
useRSqrt()192*9880d681SAndroid Build Coastguard Worker   bool useRSqrt() const { return UseRSqrt; }
getMaxInterleaveFactor()193*9880d681SAndroid Build Coastguard Worker   unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; }
getVectorInsertExtractBaseCost()194*9880d681SAndroid Build Coastguard Worker   unsigned getVectorInsertExtractBaseCost() const {
195*9880d681SAndroid Build Coastguard Worker     return VectorInsertExtractBaseCost;
196*9880d681SAndroid Build Coastguard Worker   }
getCacheLineSize()197*9880d681SAndroid Build Coastguard Worker   unsigned getCacheLineSize() const { return CacheLineSize; }
getPrefetchDistance()198*9880d681SAndroid Build Coastguard Worker   unsigned getPrefetchDistance() const { return PrefetchDistance; }
getMinPrefetchStride()199*9880d681SAndroid Build Coastguard Worker   unsigned getMinPrefetchStride() const { return MinPrefetchStride; }
getMaxPrefetchIterationsAhead()200*9880d681SAndroid Build Coastguard Worker   unsigned getMaxPrefetchIterationsAhead() const {
201*9880d681SAndroid Build Coastguard Worker     return MaxPrefetchIterationsAhead;
202*9880d681SAndroid Build Coastguard Worker   }
getPrefFunctionAlignment()203*9880d681SAndroid Build Coastguard Worker   unsigned getPrefFunctionAlignment() const { return PrefFunctionAlignment; }
getPrefLoopAlignment()204*9880d681SAndroid Build Coastguard Worker   unsigned getPrefLoopAlignment() const { return PrefLoopAlignment; }
205*9880d681SAndroid Build Coastguard Worker 
206*9880d681SAndroid Build Coastguard Worker   /// CPU has TBI (top byte of addresses is ignored during HW address
207*9880d681SAndroid Build Coastguard Worker   /// translation) and OS enables it.
208*9880d681SAndroid Build Coastguard Worker   bool supportsAddressTopByteIgnored() const;
209*9880d681SAndroid Build Coastguard Worker 
hasPerfMon()210*9880d681SAndroid Build Coastguard Worker   bool hasPerfMon() const { return HasPerfMon; }
hasFullFP16()211*9880d681SAndroid Build Coastguard Worker   bool hasFullFP16() const { return HasFullFP16; }
hasSPE()212*9880d681SAndroid Build Coastguard Worker   bool hasSPE() const { return HasSPE; }
213*9880d681SAndroid Build Coastguard Worker 
isLittleEndian()214*9880d681SAndroid Build Coastguard Worker   bool isLittleEndian() const { return IsLittle; }
215*9880d681SAndroid Build Coastguard Worker 
isTargetDarwin()216*9880d681SAndroid Build Coastguard Worker   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
isTargetIOS()217*9880d681SAndroid Build Coastguard Worker   bool isTargetIOS() const { return TargetTriple.isiOS(); }
isTargetLinux()218*9880d681SAndroid Build Coastguard Worker   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
isTargetWindows()219*9880d681SAndroid Build Coastguard Worker   bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
isTargetAndroid()220*9880d681SAndroid Build Coastguard Worker   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
221*9880d681SAndroid Build Coastguard Worker 
isTargetCOFF()222*9880d681SAndroid Build Coastguard Worker   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
isTargetELF()223*9880d681SAndroid Build Coastguard Worker   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
isTargetMachO()224*9880d681SAndroid Build Coastguard Worker   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
225*9880d681SAndroid Build Coastguard Worker 
useAA()226*9880d681SAndroid Build Coastguard Worker   bool useAA() const override { return UseAA; }
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker   /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
229*9880d681SAndroid Build Coastguard Worker   /// that still makes it profitable to inline the call.
getMaxInlineSizeThreshold()230*9880d681SAndroid Build Coastguard Worker   unsigned getMaxInlineSizeThreshold() const { return 64; }
231*9880d681SAndroid Build Coastguard Worker 
232*9880d681SAndroid Build Coastguard Worker   /// ParseSubtargetFeatures - Parses features string setting specified
233*9880d681SAndroid Build Coastguard Worker   /// subtarget options.  Definition of function is auto generated by tblgen.
234*9880d681SAndroid Build Coastguard Worker   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker   /// ClassifyGlobalReference - Find the target operand flags that describe
237*9880d681SAndroid Build Coastguard Worker   /// how a global value should be referenced for the current subtarget.
238*9880d681SAndroid Build Coastguard Worker   unsigned char ClassifyGlobalReference(const GlobalValue *GV,
239*9880d681SAndroid Build Coastguard Worker                                         const TargetMachine &TM) const;
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker   /// This function returns the name of a function which has an interface
242*9880d681SAndroid Build Coastguard Worker   /// like the non-standard bzero function, if such a function exists on
243*9880d681SAndroid Build Coastguard Worker   /// the current subtarget and it is considered prefereable over
244*9880d681SAndroid Build Coastguard Worker   /// memset with zero passed as the second argument. Otherwise it
245*9880d681SAndroid Build Coastguard Worker   /// returns null.
246*9880d681SAndroid Build Coastguard Worker   const char *getBZeroEntry() const;
247*9880d681SAndroid Build Coastguard Worker 
248*9880d681SAndroid Build Coastguard Worker   void overrideSchedPolicy(MachineSchedPolicy &Policy,
249*9880d681SAndroid Build Coastguard Worker                            unsigned NumRegionInstrs) const override;
250*9880d681SAndroid Build Coastguard Worker 
251*9880d681SAndroid Build Coastguard Worker   bool enableEarlyIfConversion() const override;
252*9880d681SAndroid Build Coastguard Worker 
253*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const override;
254*9880d681SAndroid Build Coastguard Worker };
255*9880d681SAndroid Build Coastguard Worker } // End llvm namespace
256*9880d681SAndroid Build Coastguard Worker 
257*9880d681SAndroid Build Coastguard Worker #endif
258