From 3c6a2f239a5917df764f2417bbc7dc1db431c947 Mon Sep 17 00:00:00 2001 From: Fred Chow Date: Thu, 12 Aug 2021 20:47:26 -0700 Subject: [PATCH] Add the new opcodes dreadoff, addrofoff, dassignoff and support their input/output in Maple IR --- src/mapleall/maple_ir/include/mir_nodes.h | 59 +++++++++ src/mapleall/maple_ir/include/mir_parser.h | 3 + src/mapleall/maple_ir/include/opcodes.def | 3 + src/mapleall/maple_ir/src/bin_func_export.cpp | 47 ++++--- src/mapleall/maple_ir/src/bin_func_import.cpp | 45 +++++-- src/mapleall/maple_ir/src/mir_nodes.cpp | 28 +++++ src/mapleall/maple_ir/src/mir_parser.cpp | 118 ++++++++++++++++++ 7 files changed, 277 insertions(+), 26 deletions(-) diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index a26f8ab528..90a2858501 100644 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -1283,6 +1283,29 @@ class AddrofNode : public BaseNode { // DreadNode has the same member fields and member methods as AddrofNode using DreadNode = AddrofNode; +class DreadoffNode : public BaseNode { + public: + explicit DreadoffNode(Opcode o) : BaseNode(o), stIdx() {} + + DreadoffNode(Opcode o, PrimType typ) : BaseNode(o, typ, 0), stIdx() {} + + virtual ~DreadoffNode() = default; + + void Dump(int32 indent) const override; + + DreadoffNode *CloneTree(MapleAllocator &allocator) const override { + return allocator.GetMemPool()->New(*this); + } + + bool IsVolatile(const MIRModule &mod) const; + public: + StIdx stIdx; + int32 offset = 0; +}; + +// AddrofoffNode has the same member fields and member methods as DreadoffNode +using AddrofoffNode = DreadoffNode; + class RegreadNode : public BaseNode { public: RegreadNode() : BaseNode(OP_regread) {} @@ -2054,6 +2077,42 @@ class DassignNode : public UnaryStmtNode { FieldID fieldID = 0; }; +class DassignoffNode : public UnaryStmtNode { + public: + DassignoffNode() : UnaryStmtNode(OP_dassignoff), stIdx() {} + + explicit DassignoffNode(PrimType typ) : UnaryStmtNode(OP_dassignoff, typ), stIdx() {} + + DassignoffNode(PrimType typ, BaseNode *opnd) : UnaryStmtNode(OP_dassign, typ, opnd), stIdx() {} + + virtual ~DassignoffNode() = default; + + void Dump(int32 indent) const override; + + DassignoffNode *CloneTree(MapleAllocator &allocator) const override { + auto *node = allocator.GetMemPool()->New(*this); + node->SetStmtID(stmtIDNext++); + node->SetOpnd(Opnd(0)->CloneTree(allocator), 0); + return node; + } + + size_t NumOpnds() const override { + return 1; + } + + BaseNode *GetRHS() const override { + return UnaryStmtNode::GetRHS(); + } + + void SetRHS(BaseNode *rhs) override { + UnaryStmtNode::SetOpnd(rhs, 0); + } + + public: + StIdx stIdx; + int32 offset = 0; +}; + class RegassignNode : public UnaryStmtNode { public: RegassignNode() : UnaryStmtNode(OP_regassign) {} diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index f9e673a0ea..afc6bfcd56 100644 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -101,6 +101,7 @@ class MIRParser { // Stmt Parser bool ParseStmtDassign(StmtNodePtr &stmt); + bool ParseStmtDassignoff(StmtNodePtr &stmt); bool ParseStmtRegassign(StmtNodePtr &stmt); bool ParseStmtIassign(StmtNodePtr &stmt); bool ParseStmtIassignoff(StmtNodePtr &stmt); @@ -156,6 +157,7 @@ class MIRParser { // Expression Parser bool ParseExpression(BaseNodePtr &expr); bool ParseExprDread(BaseNodePtr &expr); + bool ParseExprDreadoff(BaseNodePtr &expr); bool ParseExprRegread(BaseNodePtr &expr); bool ParseExprBinary(BaseNodePtr &expr); bool ParseExprCompare(BaseNodePtr &expr); @@ -171,6 +173,7 @@ class MIRParser { bool ParseExprIreadFPoff(BaseNodePtr &expr); bool ParseExprIaddrof(BaseNodePtr &expr); bool ParseExprAddrof(BaseNodePtr &expr); + bool ParseExprAddrofoff(BaseNodePtr &expr); bool ParseExprAddroffunc(BaseNodePtr &expr); bool ParseExprAddroflabel(BaseNodePtr &expr); bool ParseExprUnary(BaseNodePtr &expr); diff --git a/src/mapleall/maple_ir/include/opcodes.def b/src/mapleall/maple_ir/include/opcodes.def index dcb8340b41..5d83f12840 100644 --- a/src/mapleall/maple_ir/include/opcodes.def +++ b/src/mapleall/maple_ir/include/opcodes.def @@ -201,3 +201,6 @@ OPCODE(addroffpc, AddroffPCNode, 0, 0) OPCODE(igoto, UnaryStmtNode, OPCODEISSTMT, 0) OPCODE(asm, AsmNode, OPCODEISSTMT | OPCODEHASSSAUSE | OPCODEHASSSADEF | OPCODEISCALLASSIGNED, 0) + OPCODE(dreadoff, dreadoffNode, OPCODEHASSSAUSE, 12) + OPCODE(addrofoff, addrofoffNode, 0, 12) + OPCODE(dassignoff, DassignoffNode, (OPCODEISSTMT | OPCODEHASSSADEF), 8) diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 9095fa04d5..9877d13251 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -199,14 +199,24 @@ void BinaryMplExport::OutputExpression(BaseNode *e) { return; } case OP_addrof: - case OP_dread: { - AddrofNode *drNode = static_cast(e); - WriteNum(drNode->GetFieldID()); - WriteNum(drNode->GetStIdx().Scope()); - if (drNode->GetStIdx().Islocal()) { - WriteNum(drNode->GetStIdx().Idx()); // preserve original st index + case OP_addrofoff: + case OP_dread: + case OP_dreadoff: { + StIdx stIdx; + if (e->GetOpCode() == OP_addrof || e->GetOpCode() == OP_dread) { + AddrofNode *drNode = static_cast(e); + WriteNum(drNode->GetFieldID()); + stIdx = drNode->GetStIdx(); } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(drNode->GetStIdx().Idx()); + DreadoffNode *droff = static_cast(e); + WriteNum(droff->offset); + stIdx = droff->stIdx; + } + WriteNum(stIdx.Scope()); + if (stIdx.Islocal()) { + WriteNum(stIdx.Idx()); // preserve original st index + } else { + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); WriteNum(kBinKindSymViaSymname); OutputStr(sym->GetNameStrIdx()); } @@ -370,14 +380,23 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { OutputSrcPos(s->GetSrcPos()); WriteNum(s->GetOpCode()); switch (s->GetOpCode()) { - case OP_dassign: { - DassignNode *dass = static_cast(s); - WriteNum(dass->GetFieldID()); - WriteNum(dass->GetStIdx().Scope()); - if (dass->GetStIdx().Islocal()) { - WriteNum(dass->GetStIdx().Idx()); // preserve original st index + case OP_dassign: + case OP_dassignoff: { + StIdx stIdx; + if (s->GetOpCode() == OP_dassign) { + DassignNode *dass = static_cast(s); + WriteNum(dass->GetFieldID()); + stIdx = dass->GetStIdx(); + } else { + DassignoffNode *dassoff = static_cast(s); + WriteNum(dassoff->offset); + stIdx = dassoff->stIdx; + } + WriteNum(stIdx.Scope()); + if (stIdx.Islocal()) { + WriteNum(stIdx.Idx()); // preserve original st index } else { - MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(dass->GetStIdx().Idx()); + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx()); WriteNum(kBinKindSymViaSymname); OutputStr(sym->GetNameStrIdx()); } diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index d090d34da8..40cdfb8ac2 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -228,10 +228,10 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { return sot; } case OP_addrof: - case OP_dread: { - AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); - drNode->SetPrimType(typ); - drNode->SetFieldID(ReadNum()); + case OP_addrofoff: + case OP_dread: + case OP_dreadoff: { + int32 num = ReadNum(); StIdx stIdx; stIdx.SetScope(ReadNum()); if (stIdx.Islocal()) { @@ -246,8 +246,19 @@ BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func) { } stIdx.SetIdx(sym->GetStIdx().Idx()); } - drNode->SetStIdx(stIdx); - return drNode; + if (op == OP_addrof || op == OP_dread) { + AddrofNode *drNode = mod.CurFuncCodeMemPool()->New(op); + drNode->SetPrimType(typ); + drNode->SetStIdx(stIdx); + drNode->SetFieldID(num); + return drNode; + } else { + DreadoffNode *dreadoff = mod.CurFuncCodeMemPool()->New(op); + dreadoff->SetPrimType(typ); + dreadoff->stIdx = stIdx; + dreadoff->offset = num; + return dreadoff; + } } case OP_regread: { RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New(); @@ -464,9 +475,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { op = (Opcode)ReadNum(); StmtNode *stmt = nullptr; switch (op) { - case OP_dassign: { - DassignNode *s = func->GetCodeMemPool()->New(); - s->SetFieldID(ReadNum()); + case OP_dassign: + case OP_dassignoff: { + int32 num = ReadNum(); StIdx stIdx; stIdx.SetScope(ReadNum()); if (stIdx.Islocal()) { @@ -479,9 +490,19 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { sym->SetHasPotentialAssignment(); stIdx.SetIdx(sym->GetStIdx().Idx()); } - s->SetStIdx(stIdx); - s->SetOpnd(ImportExpression(func), 0); - stmt = s; + if (op == OP_dassign) { + DassignNode *s = func->GetCodeMemPool()->New(); + s->SetStIdx(stIdx); + s->SetFieldID(num); + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + } else { + DassignoffNode *s = func->GetCodeMemPool()->New(); + s->stIdx = stIdx; + s->offset = num; + s->SetOpnd(ImportExpression(func), 0); + stmt = s; + } break; } case OP_regassign: { diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 9580f3cb2f..953a44cfd0 100644 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -147,6 +147,12 @@ bool AddrofNode::IsVolatile(const MIRModule &mod) const { return symbol->IsVolatile(); } +bool DreadoffNode::IsVolatile(const MIRModule &mod) const { + auto *symbol = mod.CurFunction()->GetLocalOrGlobalSymbol(stIdx); + ASSERT(symbol != nullptr, "null ptr check on symbol"); + return symbol->IsVolatile(); +} + bool DassignNode::AssigningVolatile(const MIRModule &mod) const { auto *symbol = mod.CurFunction()->GetLocalOrGlobalSymbol(stIdx); ASSERT(symbol != nullptr, "null ptr check on symbol"); @@ -555,6 +561,14 @@ void AddrofNode::Dump(int32) const { } } +void DreadoffNode::Dump(int32) const { + LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name << " " << GetPrimTypeName(GetPrimType()); + const MIRSymbol *st = theMIRModule->CurFunction()->GetLocalOrGlobalSymbol(stIdx); + LogInfo::MapleLogger() << (stIdx.Islocal() ? " %" : " $"); + LogInfo::MapleLogger() << st->GetName(); + LogInfo::MapleLogger() << " " << offset; +} + void RegreadNode::Dump(int32) const { LogInfo::MapleLogger() << kOpcodeInfo.GetTableItemAt(GetOpCode()).name << " " << GetPrimTypeName(GetPrimType()); if (regIdx >= 0) { @@ -662,6 +676,20 @@ void DassignNode::Dump(int32 indent) const { LogInfo::MapleLogger() << ")\n"; } +void DassignoffNode::Dump(int32 indent) const { + StmtNode::DumpBase(indent); + const MIRSymbol *st = theMIRModule->CurFunction()->GetLocalOrGlobalSymbol(stIdx); + LogInfo::MapleLogger() << (st->IsLocal() ? " %" : " $"); + LogInfo::MapleLogger() << st->GetName() << " " << offset; + LogInfo::MapleLogger() << " ("; + if (GetRHS() != nullptr) { + GetRHS()->Dump(indent + 1); + } else { + LogInfo::MapleLogger() << "/*empty-rhs*/"; + } + LogInfo::MapleLogger() << ")\n"; +} + void RegassignNode::Dump(int32 indent) const { StmtNode::DumpBase(indent); LogInfo::MapleLogger() << " " << GetPrimTypeName(GetPrimType()); diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 1af4e0e6ed..76ee9f8999 100644 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -62,6 +62,47 @@ bool MIRParser::ParseStmtDassign(StmtNodePtr &stmt) { return true; } +bool MIRParser::ParseStmtDassignoff(StmtNodePtr &stmt) { + if (lexer.GetTokenKind() != TK_dassignoff) { + Error("expect dassignoff but get "); + return false; + } + // parse %i + lexer.NextToken(); + StIdx stidx; + if (!ParseDeclaredSt(stidx)) { + return false; + } + if (stidx.FullIdx() == 0) { + Error("expect a symbol parsing ParseStmtDassign"); + return false; + } + if (stidx.IsGlobal()) { + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx()); + sym->SetHasPotentialAssignment(); + } + DassignoffNode *assignStmt = mod.CurFuncCodeMemPool()->New(); + assignStmt->stIdx = stidx; + TokenKind nextToken = lexer.NextToken(); + // parse offset + if (nextToken == TK_intconst) { + assignStmt->offset = lexer.GetTheIntVal(); + (void)lexer.NextToken(); + } else { + Error("expect integer offset but get "); + return false; + } + // parse expression like (constval i32 0) + BaseNode *expr = nullptr; + if (!ParseExprOneOperand(expr)) { + return false; + } + assignStmt->SetRHS(expr); + stmt = assignStmt; + lexer.NextToken(); + return true; +} + bool MIRParser::ParseStmtRegassign(StmtNodePtr &stmt) { if (!IsPrimitiveType(lexer.NextToken())) { Error("expect type parsing binary operator but get "); @@ -2009,6 +2050,41 @@ bool MIRParser::ParseExprDread(BaseNodePtr &expr) { return true; } +bool MIRParser::ParseExprDreadoff(BaseNodePtr &expr) { + if (lexer.GetTokenKind() != TK_dreadoff) { + Error("expect dreadoff but get "); + return false; + } + DreadoffNode *dexpr = mod.CurFuncCodeMemPool()->New(OP_dreadoff); + expr = dexpr; + lexer.NextToken(); + TyIdx tyidx(0); + bool parseRet = ParsePrimType(tyidx); + if (tyidx == 0u || !parseRet) { + Error("expect primitive type but get "); + return false; + } + expr->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx)); + StIdx stidx; + if (!ParseDeclaredSt(stidx)) { + return false; + } + if (stidx.FullIdx() == 0) { + Error("expect a symbol ParseExprDread failed"); + return false; + } + dexpr->stIdx = stidx; + TokenKind endtk = lexer.NextToken(); + if (endtk == TK_intconst) { + dexpr->offset = lexer.GetTheIntVal(); + lexer.NextToken(); + } else { + Error("expect integer offset but get "); + return false; + } + return true; +} + bool MIRParser::ParseExprRegread(BaseNodePtr &expr) { auto *regRead = mod.CurFuncCodeMemPool()->New(); expr = regRead; @@ -2400,6 +2476,45 @@ bool MIRParser::ParseExprAddrof(BaseNodePtr &expr) { return true; } +bool MIRParser::ParseExprAddrofoff(BaseNodePtr &expr) { + // syntax: addrofoff + AddrofoffNode *addrofoffNode = mod.CurFuncCodeMemPool()->New(OP_addrofoff); + expr = addrofoffNode; + if (lexer.GetTokenKind() != TK_addrofoff) { + Error("expect addrofoff but get "); + return false; + } + lexer.NextToken(); + TyIdx tyidx(0); + if (!ParsePrimType(tyidx)) { + Error("expect primitive type but get "); + return false; + } + addrofoffNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx)); + StIdx stidx; + if (!ParseDeclaredSt(stidx)) { + return false; + } + if (stidx.FullIdx() == 0) { + Error("expect symbol ParseExprAddroffunc"); + return false; + } + if (stidx.IsGlobal()) { + MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx()); + sym->SetHasPotentialAssignment(); + } + addrofoffNode->stIdx = stidx; + TokenKind tk = lexer.NextToken(); + if (tk == TK_intconst) { + addrofoffNode->offset = lexer.GetTheIntVal(); + lexer.NextToken(); + } else { + Error("expect integer offset but get "); + return false; + } + return true; +} + bool MIRParser::ParseExprAddroffunc(BaseNodePtr &expr) { auto *addrOfFuncNode = mod.CurFuncCodeMemPool()->New(); expr = addrOfFuncNode; @@ -2904,6 +3019,7 @@ bool MIRParser::ParseExpression(BaseNodePtr &expr) { std::map MIRParser::InitFuncPtrMapForParseExpr() { std::map funcPtrMap; funcPtrMap[TK_addrof] = &MIRParser::ParseExprAddrof; + funcPtrMap[TK_addrofoff] = &MIRParser::ParseExprAddrofoff; funcPtrMap[TK_addroffunc] = &MIRParser::ParseExprAddroffunc; funcPtrMap[TK_addroflabel] = &MIRParser::ParseExprAddroflabel; funcPtrMap[TK_abs] = &MIRParser::ParseExprUnary; @@ -2941,6 +3057,7 @@ std::map MIRParser::InitFuncPtrMapForPar funcPtrMap[TK_ireadoff] = &MIRParser::ParseExprIreadoff; funcPtrMap[TK_ireadfpoff] = &MIRParser::ParseExprIreadFPoff; funcPtrMap[TK_dread] = &MIRParser::ParseExprDread; + funcPtrMap[TK_dreadoff] = &MIRParser::ParseExprDreadoff; funcPtrMap[TK_regread] = &MIRParser::ParseExprRegread; funcPtrMap[TK_add] = &MIRParser::ParseExprBinary; funcPtrMap[TK_ashr] = &MIRParser::ParseExprBinary; @@ -2976,6 +3093,7 @@ std::map MIRParser::InitFuncPtrMapForPar std::map MIRParser::InitFuncPtrMapForParseStmt() { std::map funcPtrMap; funcPtrMap[TK_dassign] = &MIRParser::ParseStmtDassign; + funcPtrMap[TK_dassignoff] = &MIRParser::ParseStmtDassignoff; funcPtrMap[TK_iassign] = &MIRParser::ParseStmtIassign; funcPtrMap[TK_iassignoff] = &MIRParser::ParseStmtIassignoff; funcPtrMap[TK_iassignfpoff] = &MIRParser::ParseStmtIassignFPoff; -- Gitee