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 Operand *SelectFloatingConst(MIRConst &floatingConst, PrimType primType) const = 0; 75 virtual Operand &ProcessReturnReg(PrimType primType, int32 sReg) = 0; 76 virtual void SelectCondGoto(CondGotoNode &stmt, BaseNode &condNode, Operand &opnd0) = 0; 77 Operand *SelectBior(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 78 Operand *SelectBxor(const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 79 Operand *SelectIread(const BaseNode &parent, const IreadNode &expr, int extraOffset = 0); 80 virtual Operand *SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 81 virtual Operand *SelectDiv(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 82 virtual Operand *SelectRem(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 83 virtual Operand *SelectCmpOp(CompareNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) = 0; 84 virtual Operand *SelectCclz(IntrinsicopNode &node, Operand &opnd0, const BaseNode &parent) = 0; 85 virtual Operand *SelectCctz(IntrinsicopNode &node, Operand &opnd0, const BaseNode &parent) = 0; 86 Operand *SelectBnot(const UnaryNode &node, Operand &opnd0, const BaseNode &parent); 87 virtual Operand *SelectLnot(const UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0; 88 Operand *SelectMin(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 89 Operand *SelectMax(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); 90 Operand *SelectRetype(TypeCvtNode &node, Operand &opnd0); 91 virtual RegOperand &SelectSpecialRegread(PregIdx pregIdx, PrimType primType) = 0; 92 virtual Operand *SelectSqrt(UnaryNode &node, Operand &opnd0, const BaseNode &parent) = 0; 93 94 template <typename T> SelectLiteral(T & c,MIRFunction & func,uint32 labelIdx)95 Operand *SelectLiteral(T &c, MIRFunction &func, uint32 labelIdx) const 96 { 97 MIRSymbol *st = func.GetSymTab()->CreateSymbol(kScopeLocal); 98 std::string lblStr(".LB_"); 99 MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx()); 100 CHECK_FATAL(funcSt != nullptr, "must not be null pointer"); 101 std::string funcName = funcSt->GetName(); 102 (void)lblStr.append(funcName).append(std::to_string(labelIdx)); 103 st->SetNameStrIdx(lblStr); 104 st->SetStorageClass(kScPstatic); 105 st->SetSKind(kStConst); 106 st->SetKonst(&c); 107 PrimType primType = c.GetType().GetPrimType(); 108 st->SetTyIdx(TyIdx(primType)); 109 uint32 typeBitSize = GetPrimTypeBitSize(primType); 110 111 // maybe need judge cgFunc->GetMirModule().IsXModule 112 if ((T::GetPrimType() == PTY_f32 || T::GetPrimType() == PTY_f64)) { 113 return &GetOrCreateMemOpndFromSymbol(*st, typeBitSize, 0); 114 } 115 CHECK_FATAL(false, "NIY"); 116 return nullptr; 117 } 118 119 protected: 120 MemPool *isMp; 121 CGFunc *cgFunc; 122 123 void SelectCopy(Operand &dest, Operand &src, PrimType toType, PrimType fromType); 124 void SelectCopy(Operand &dest, Operand &src, PrimType toType); 125 RegOperand &SelectCopy2Reg(Operand &src, PrimType toType, PrimType fromType); 126 RegOperand &SelectCopy2Reg(Operand &src, PrimType toType); 127 void SelectIntCvt(RegOperand &resOpnd, Operand &opnd0, PrimType toType, PrimType fromType); 128 void SelectCvtInt2Float(RegOperand &resOpnd, Operand &origOpnd0, PrimType toType, PrimType fromType); 129 void SelectFloatCvt(RegOperand &resOpnd, Operand &opnd0, PrimType toType, PrimType fromType); 130 void SelectCvtFloat2Int(RegOperand &resOpnd, Operand &origOpnd0, PrimType toType, PrimType fromType); 131 PrimType GetIntegerPrimTypeFromSize(bool isSigned, uint32 bitSize); 132 std::pair<FieldID, MIRType *> GetFieldIdAndMirTypeFromMirNode(const BaseNode &node); 133 MirTypeInfo GetMirTypeInfoFormFieldIdAndMirType(FieldID fieldId, MIRType *mirType); 134 MirTypeInfo GetMirTypeInfoFromMirNode(const BaseNode &node); 135 MemOperand *GetOrCreateMemOpndFromIreadNode(const IreadNode &expr, PrimType primType, int offset); 136 137 private: 138 StmtNode *HandleFuncEntry(); 139 void HandleFuncExit(); 140 void SelectDassign(StIdx stIdx, FieldID fieldId, PrimType rhsPType, Operand &opndRhs); 141 virtual MemOperand &GetOrCreateMemOpndFromSymbol(const MIRSymbol &symbol, FieldID fieldId = 0) const = 0; 142 virtual MemOperand &GetOrCreateMemOpndFromSymbol(const MIRSymbol &symbol, uint32 opndSize, int64 offset) const = 0; 143 virtual Operand &GetTargetRetOperand(PrimType primType, int32 sReg) = 0; 144 void SelectBasicOp(Operand &resOpnd, Operand &opnd0, Operand &opnd1, MOperator mOp, PrimType primType); 145 /* 146 * Support conversion between all types and registers 147 * only Support conversion between registers and memory 148 * alltypes -> reg -> mem 149 */ 150 void SelectCopyInsn(Operand &dest, Operand &src, PrimType type); 151 void SelectNeg(Operand &resOpnd, Operand &opnd0, PrimType primType); 152 void SelectBnot(Operand &resOpnd, Operand &opnd0, PrimType primType); 153 void SelectBior(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 154 void SelectExtractbits(RegOperand &resOpnd, RegOperand &opnd0, uint8 bitOffset, uint8 bitSize, PrimType primType); 155 void SelectBxor(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 156 virtual RegOperand &GetTargetBasicPointer(PrimType primType) = 0; 157 void SelectMin(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 158 void SelectMax(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); 159 virtual void SelectMinOrMax(bool isMin, Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) = 0; 160 /* retype float/double reg to int64 reg, or i64 reg to f64 reg: no changing bit mov */ 161 virtual void SelectRetypeFloat(RegOperand &resOpnd, Operand &opnd0, PrimType toType, PrimType fromType) = 0; 162 }; 163 MAPLE_FUNC_PHASE_DECLARE_BEGIN(InstructionSelector, maplebe::CGFunc) 164 MAPLE_FUNC_PHASE_DECLARE_END 165 } // namespace maplebe 166 #endif /* MAPLEBE_INCLUDE_CG_ISEL_H */ 167