1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MAPLEBE_INCLUDE_CG_ISEL_H 17 #define MAPLEBE_INCLUDE_CG_ISEL_H 18 19 #include "cgfunc.h" 20 21 namespace maplebe { 22 struct MirTypeInfo { 23 PrimType primType; 24 int32 offset = 0; 25 uint32 size = 0; /* for aggType */ 26 }; 27 /* macro expansion instruction selection */ 28 class MPISel { 29 public: MPISel(MemPool & mp,MapleAllocator & allocator,CGFunc & f)30 MPISel(MemPool &mp, MapleAllocator &allocator, CGFunc &f) : isMp(&mp), cgFunc(&f) {} 31 ~MPISel()32 virtual ~MPISel() 33 { 34 isMp = nullptr; 35 cgFunc = nullptr; 36 } 37 38 void doMPIS(); 39 GetCurFunc()40 CGFunc *GetCurFunc() const 41 { 42 return cgFunc; 43 } 44 45 Operand *HandleExpr(const BaseNode &parent, BaseNode &expr); 46 47 void SelectDassign(const DassignNode &stmt, Operand &opndRhs); 48 void SelectIassign(const IassignNode &stmt, Operand &opndAddr, Operand &opndRhs); 49 RegOperand *SelectRegread(RegreadNode &expr); 50 void SelectRegassign(RegassignNode &stmt, Operand &opnd0); 51 Operand *SelectDread(const BaseNode &parent, const AddrofNode &expr); 52 Operand *SelectBand(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 53 Operand *SelectAdd(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 54 Operand *SelectSub(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 55 Operand *SelectNeg(const UnaryNode &node, Operand &opnd0, const BaseNode &parent); 56 Operand *SelectCvt(const BaseNode &parent, const TypeCvtNode &node, Operand &opnd0); 57 Operand *SelectExtractbits(const BaseNode &parent, const ExtractbitsNode &node, Operand &opnd0); 58 virtual Operand *SelectAbs(UnaryNode &node, Operand &opnd0); 59 ImmOperand *SelectIntConst(const MIRIntConst &intConst, PrimType primType); 60 void SelectCallCommon(StmtNode &stmt, const MPISel &iSel); 61 void SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 62 void SelectSub(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 63 Operand *SelectShift(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 64 void SelectShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, Opcode shiftDirect, PrimType opnd0Type, 65 PrimType opnd1Type); 66 void SelectBand(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 67 virtual void SelectReturn(NaryStmtNode &retNode, Operand &opnd) = 0; 68 virtual void SelectReturn() = 0; 69 virtual void SelectGoto(GotoNode &stmt) = 0; 70 virtual void SelectRangeGoto(RangeGotoNode &rangeGotoNode, Operand &srcOpnd) = 0; 71 virtual void SelectCall(CallNode &callNode) = 0; 72 virtual void SelectIcall(IcallNode &icallNode) = 0; 73 virtual void SelectIntrinsicCall(IntrinsiccallNode &intrinsiccallNode) = 0; 74 virtual void SelectDeoptCall(CallNode &callNode) = 0; 75 virtual void SelectTailICall(IcallNode &icallNode) = 0; 76 virtual Operand *SelectFloatingConst(MIRConst &floatingConst, PrimType primType) const = 0; 77 virtual Operand &ProcessReturnReg(PrimType primType, int32 sReg) = 0; 78 virtual void SelectCondGoto(CondGotoNode &stmt, BaseNode &condNode, Operand &opnd0) = 0; 79 Operand *SelectBior(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 80 Operand *SelectBxor(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 81 Operand *SelectIread(const BaseNode &parent, const IreadNode &expr, int extraOffset = 0); 82 virtual Operand *SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 83 virtual Operand *SelectDiv(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 84 virtual Operand *SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 85 virtual Operand *SelectCmpOp(CompareNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 86 virtual Operand *SelectCclz(IntrinsicopNode &node, Operand &opnd0, const BaseNode &parent) = 0; 87 virtual Operand *SelectCctz(IntrinsicopNode &node, Operand &opnd0, const BaseNode &parent) = 0; 88 virtual RegOperand &SelectHeapConstant( 89 IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 90 virtual RegOperand &SelectTaggedIsHeapObject(IntrinsicopNode &node, Operand &opnd0, 91 Operand &opnd1, const BaseNode &parent) = 0; 92 virtual RegOperand &SelectIsStableElements(IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, 93 Operand &opnd2, const BaseNode &parent) = 0; 94 virtual RegOperand &SelectHasPendingException( 95 IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, Operand &opnd2, const BaseNode &parent) = 0; 96 virtual RegOperand &SelectGetHeapConstantTable( 97 IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, Operand &opnd2, const BaseNode &parent) = 0; 98 virtual RegOperand &SelectTaggedObjectIsString( 99 IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, Operand &opnd2, Operand &opnd3, 100 Operand &opnd4, const BaseNode &parent) = 0; 101 virtual RegOperand &SelectIsCOWArray( 102 IntrinsicopNode &node, Operand &opnd0, Operand &opnd1, Operand &opnd2, Operand &opnd3, 103 Operand &opnd4, Operand &opnd5, const BaseNode &parent) = 0; 104 Operand *SelectBnot(const UnaryNode &node, Operand &opnd0, const BaseNode &parent); 105 virtual Operand *SelectLnot(const UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0; 106 Operand *SelectMin(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 107 Operand *SelectMax(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 108 Operand *SelectRetype(TypeCvtNode &node, Operand &opnd0); 109 virtual RegOperand &SelectSpecialRegread(PregIdx pregIdx, PrimType primType) = 0; 110 virtual Operand *SelectSqrt(UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0; 111 112 template <typename T> SelectLiteral(T & c,MIRFunction & func,uint32 labelIdx)113 Operand *SelectLiteral(T &c, MIRFunction &func, uint32 labelIdx) const 114 { 115 MIRSymbol *st = func.GetSymTab()->CreateSymbol(kScopeLocal); 116 std::string lblStr(".LB_"); 117 MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx()); 118 CHECK_FATAL(funcSt != nullptr, "must not be null pointer"); 119 std::string funcName = funcSt->GetName(); 120 (void)lblStr.append(funcName).append(std::to_string(labelIdx)); 121 st->SetNameStrIdx(lblStr); 122 st->SetStorageClass(kScPstatic); 123 st->SetSKind(kStConst); 124 st->SetKonst(&c); 125 PrimType primType = c.GetType().GetPrimType(); 126 st->SetTyIdx(TyIdx(primType)); 127 uint32 typeBitSize = GetPrimTypeBitSize(primType); 128 129 // maybe need judge cgFunc->GetMirModule().IsXModule 130 if ((T::GetPrimType() == PTY_f32 || T::GetPrimType() == PTY_f64)) { 131 return &GetOrCreateMemOpndFromSymbol(*st, typeBitSize, 0); 132 } 133 CHECK_FATAL(false, "NIY"); 134 return nullptr; 135 } 136 137 protected: 138 MemPool *isMp; 139 CGFunc *cgFunc; 140 141 void SelectCopy(Operand &dest, Operand &src, PrimType toType, PrimType fromType); 142 void SelectCopy(Operand &dest, Operand &src, PrimType toType); 143 RegOperand &SelectCopy2Reg(Operand &src, PrimType toType, PrimType fromType); 144 RegOperand &SelectCopy2Reg(Operand &src, PrimType toType); 145 void SelectIntCvt(RegOperand &resOpnd, Operand &opnd0, PrimType toType, PrimType fromType); 146 void SelectCvtInt2Float(RegOperand &resOpnd, Operand &origOpnd0, PrimType toType, PrimType fromType); 147 void SelectFloatCvt(RegOperand &resOpnd, Operand &opnd0, PrimType toType, PrimType fromType); 148 void SelectCvtFloat2Int(RegOperand &resOpnd, Operand &origOpnd0, PrimType toType, PrimType fromType); 149 PrimType GetIntegerPrimTypeFromSize(bool isSigned, uint32 bitSize); 150 std::pair<FieldID, MIRType *> GetFieldIdAndMirTypeFromMirNode(const BaseNode &node); 151 MirTypeInfo GetMirTypeInfoFormFieldIdAndMirType(FieldID fieldId, MIRType *mirType); 152 MirTypeInfo GetMirTypeInfoFromMirNode(const BaseNode &node); 153 MemOperand *GetOrCreateMemOpndFromIreadNode(const IreadNode &expr, PrimType primType, int offset); 154 155 private: 156 StmtNode *HandleFuncEntry(); 157 void HandleFuncExit(); 158 void SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPType, Operand &opndRhs); 159 virtual MemOperand &GetOrCreateMemOpndFromSymbol(const MIRSymbol &symbol, FieldID fieldId = 0) const = 0; 160 virtual MemOperand &GetOrCreateMemOpndFromSymbol(const MIRSymbol &symbol, uint32 opndSize, int64 offset) const = 0; 161 virtual Operand &GetTargetRetOperand(PrimType primType, int32 sReg) = 0; 162 void SelectBasicOp(Operand &resOpnd, Operand &opnd0, Operand &opnd1, MOperator mOp, PrimType primType); 163 /* 164 * Support conversion between all types and registers 165 * only Support conversion between registers and memory 166 * alltypes -> reg -> mem 167 */ 168 void SelectCopyInsn(Operand &dest, Operand &src, PrimType type); 169 void SelectNeg(Operand &resOpnd, Operand &opnd0, PrimType primType); 170 void SelectBnot(Operand &resOpnd, Operand &opnd0, PrimType primType); 171 void SelectBior(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 172 void SelectExtractbits(RegOperand &resOpnd, RegOperand &opnd0, uint8 bitOffset, uint8 bitSize, PrimType primType); 173 void SelectBxor(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 174 virtual RegOperand &GetTargetBasicPointer(PrimType primType) = 0; 175 void SelectMin(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 176 void SelectMax(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 177 virtual void SelectMinOrMax(bool isMin, Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0; 178 /* retype float/double reg to int64 reg, or i64 reg to f64 reg: no changing bit mov */ 179 virtual void SelectRetypeFloat(RegOperand &resOpnd, Operand &opnd0, PrimType toType, PrimType fromType) = 0; 180 }; 181 MAPLE_FUNC_PHASE_DECLARE_BEGIN(InstructionSelector, maplebe::CGFunc) 182 MAPLE_FUNC_PHASE_DECLARE_END 183 } // namespace maplebe 184 #endif /* MAPLEBE_INCLUDE_CG_ISEL_H */ 185