diff --git a/src/mapleall/maple_ir/include/mir_builder.h b/src/mapleall/maple_ir/include/mir_builder.h index 0ee756d70e09253692aed8601a609be06bd61021..ac3215724ed4eb1a5493131c835f4a42ff7fba9d 100755 --- a/src/mapleall/maple_ir/include/mir_builder.h +++ b/src/mapleall/maple_ir/include/mir_builder.h @@ -193,7 +193,8 @@ class MIRBuilder { virtual AddrofNode *CreateExprDread(MIRType &type, MIRSymbol &symbol); virtual AddrofNode *CreateExprDread(MIRSymbol &symbol); AddrofNode *CreateExprDread(PregIdx pregID, PrimType pty); - AddrofNode *CreateExprDread(MIRSymbol&, uint16); + AddrofNode *CreateExprDread(MIRSymbol &symbol, uint16 fieldID); + DreadoffNode *CreateExprDreadoff(Opcode op, PrimType pty, MIRSymbol &symbol, int32 offset); RegreadNode *CreateExprRegread(PrimType pty, PregIdx regIdx); IreadNode *CreateExprIread(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID, BaseNode *addr); IreadoffNode *CreateExprIreadoff(PrimType pty, int32 offset, BaseNode *opnd0); @@ -201,6 +202,10 @@ class MIRBuilder { IaddrofNode *CreateExprIaddrof(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID, BaseNode *addr); IaddrofNode *CreateExprIaddrof(PrimType returnTypePty, TyIdx ptrTypeIdx, FieldID fieldID, BaseNode *addr); BinaryNode *CreateExprBinary(Opcode opcode, const MIRType &type, BaseNode *opnd0, BaseNode *opnd1); + BinaryNode *CreateExprBinary(Opcode opcode, PrimType pty, BaseNode *opnd0, BaseNode *opnd1) { + MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)pty); + return CreateExprBinary(opcode, *ty, opnd0, opnd1); + } TernaryNode *CreateExprTernary(Opcode opcode, const MIRType &type, BaseNode *opnd0, BaseNode *opnd1, BaseNode *opnd2); CompareNode *CreateExprCompare(Opcode opcode, const MIRType &type, const MIRType &opndType, BaseNode *opnd0, BaseNode *opnd1); diff --git a/src/mapleall/maple_ir/include/mir_nodes.h b/src/mapleall/maple_ir/include/mir_nodes.h index 54a99c6b03191a9018c3c2455a0e284f88a47eea..e14704bbc73667d01aa63fe936f8876713e8660e 100755 --- a/src/mapleall/maple_ir/include/mir_nodes.h +++ b/src/mapleall/maple_ir/include/mir_nodes.h @@ -2353,12 +2353,12 @@ class BlockNode : public StmtNode { // insert all the stmts in inblock to the current block after stmt1 void InsertBlockAfter(BlockNode &inblock, const StmtNode *stmt1); void Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable *thePregTab, - bool withInfo, bool isFuncbody) const; + bool withInfo, bool isFuncbody, MIRFlavor flavor) const; bool Verify() const override; bool Verify(VerifyResult &verifyResult) const override; void Dump(int32 indent) const override { - Dump(indent, nullptr, nullptr, false, false); + Dump(indent, nullptr, nullptr, false, false, kFlavorUnknown); } BlockNode *CloneTree(MapleAllocator &allocator) const override { @@ -2834,10 +2834,11 @@ typedef IassignFPoffNode IassignPCoffNode; class BlkassignoffNode : public BinaryStmtNode { public: - BlkassignoffNode() : BinaryStmtNode(OP_blkassignoff) { ptyp = PTY_agg; } - explicit BlkassignoffNode(int32 ofst, int32 bsize) : BinaryStmtNode(OP_blkassignoff), offset(ofst), blockSize(bsize) { ptyp = PTY_agg; } + BlkassignoffNode() : BinaryStmtNode(OP_blkassignoff) { ptyp = PTY_agg; alignLog2 = 0; offset = 0; } + explicit BlkassignoffNode(int32 ofst, int32 bsize) : BinaryStmtNode(OP_blkassignoff), offset(ofst), blockSize(bsize) { ptyp = PTY_agg; alignLog2 = 0; } explicit BlkassignoffNode(int32 ofst, int32 bsize, BaseNode *dest, BaseNode *src) : BinaryStmtNode(OP_blkassignoff), offset(ofst), blockSize(bsize) { ptyp = PTY_agg; + alignLog2 = 0; SetBOpnd(dest, 0); SetBOpnd(src, 1); } @@ -2852,8 +2853,29 @@ class BlkassignoffNode : public BinaryStmtNode { node->SetBOpnd(GetBOpnd(1)->CloneTree(allocator), 1); return node; } + uint32 GetAlign() const { + uint32 res = 1; + for (uint32 i = 0; i < alignLog2; i++) { + res *= 2; + } + return res; + } + void SetAlign(uint32 x) { + if (x == 0) { + alignLog2 = 0; + return; + } + ASSERT((~(x - 1) & x) == x, "SetAlign called with non power of 2"); + uint32 res = 0; + while (x != 1) { + x >>= 1; + ++res; + } + alignLog2 = res; + } public: - int32 offset = 0; + uint32 alignLog2:4; // alignment in bytes encoded in log2 + int32 offset:28; int32 blockSize = 0; }; diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 0edb258fe8f0088fc16cc423340c853698d522b5..c73b172c9886a2d5d62520da35f3480b38266ebc 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -479,6 +479,19 @@ class MIRSymbol { return storageClass == kScFormal; } + bool LMBCAllocateOffSpecialReg() { + if (isDeleted) { + return false; + } + switch (storageClass) { + case kScFormal: + case kScAuto: return true; + case kScPstatic: + case kScFstatic: return value.konst == nullptr; + default: return false; + } + } + // Please keep order of the fields, avoid paddings. private: TyIdx tyIdx{ 0 }; @@ -574,7 +587,7 @@ class MIRSymbolTable { return GetSymbolFromStIdx(GetStIdxFromStrIdx(idx).Idx(), checkFirst); } - void Dump(bool isLocal, int32 indent = 0, bool printDeleted = false) const; + void Dump(bool isLocal, int32 indent = 0, bool printDeleted = false, MIRFlavor flavor = kFlavorUnknown) const; size_t GetSymbolTableSize() const { return symbolTable.size(); } diff --git a/src/mapleall/maple_ir/src/bin_func_export.cpp b/src/mapleall/maple_ir/src/bin_func_export.cpp index 07b1d9eeab5ad3ef0dac8c0f735030a48f4e30d9..843a7693ca10c4a9880c104416ff5f9de85a0402 100644 --- a/src/mapleall/maple_ir/src/bin_func_export.cpp +++ b/src/mapleall/maple_ir/src/bin_func_export.cpp @@ -451,7 +451,8 @@ void BinaryMplExport::OutputBlockNode(BlockNode *block) { } case OP_blkassignoff: { BlkassignoffNode *bass = static_cast(s); - WriteNum(bass->offset); + int32 offsetAlign = (bass->offset << 4) | bass->alignLog2; + WriteNum(offsetAlign); WriteNum(bass->blockSize); break; } diff --git a/src/mapleall/maple_ir/src/bin_func_import.cpp b/src/mapleall/maple_ir/src/bin_func_import.cpp index 7195b191727648cbe78b1154c617cedec5dfd621..f956ed2070a404e47e371d22e1d7120782bbb9c0 100644 --- a/src/mapleall/maple_ir/src/bin_func_import.cpp +++ b/src/mapleall/maple_ir/src/bin_func_import.cpp @@ -559,7 +559,9 @@ BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func) { } case OP_blkassignoff: { BlkassignoffNode *s = func->GetCodeMemPool()->New(); - s->offset = static_cast(ReadNum()); + int32 offsetAlign = ReadNum(); + s->offset = offsetAlign >> 4; + s->alignLog2 = offsetAlign & 0xf; s->blockSize = static_cast(ReadNum()); s->SetOpnd(ImportExpression(func), 0); s->SetOpnd(ImportExpression(func), 1); diff --git a/src/mapleall/maple_ir/src/mir_builder.cpp b/src/mapleall/maple_ir/src/mir_builder.cpp index abec8b50d9809d10f206974ff5f6d824f72a77b6..0c16e53443f234cddb14453ae4aace066bb6d310 100755 --- a/src/mapleall/maple_ir/src/mir_builder.cpp +++ b/src/mapleall/maple_ir/src/mir_builder.cpp @@ -642,6 +642,13 @@ AddrofNode *MIRBuilder::CreateExprDread(PregIdx pregID, PrimType pty) { return dread; } +DreadoffNode *MIRBuilder::CreateExprDreadoff(Opcode op, PrimType pty, MIRSymbol &symbol, int32 offset) { + DreadoffNode *node = GetCurrentFuncCodeMp()->New(op, pty); + node->stIdx = symbol.GetStIdx(); + node->offset = offset; + return node; +} + IreadNode *MIRBuilder::CreateExprIread(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID, BaseNode *addr) { TyIdx returnTypeIdx = returnType.GetTypeIndex(); diff --git a/src/mapleall/maple_ir/src/mir_function.cpp b/src/mapleall/maple_ir/src/mir_function.cpp index 75cafccb6b8d978e80c49182cb822073760316f3..46674af8ac71b948f2c88e9226f5b9082b27c0f3 100644 --- a/src/mapleall/maple_ir/src/mir_function.cpp +++ b/src/mapleall/maple_ir/src/mir_function.cpp @@ -371,8 +371,9 @@ void MIRFunction::Dump(bool withoutBody) { LogInfo::MapleLogger() << '\n'; } else if (GetBody() != nullptr && !withoutBody && symbol->GetStorageClass() != kScExtern) { ResetInfoPrinted(); // this ensures funcinfo will be printed - GetBody()->Dump(0, module->GetFlavor() < kMmpl ? GetSymTab() : nullptr, - module->GetFlavor() < kMmpl ? GetPregTab() : nullptr, false, true); // Dump body + GetBody()->Dump(0, module->GetFlavor() == kMmpl ? nullptr : GetSymTab(), + module->GetFlavor() < kMmpl ? GetPregTab() : nullptr, false, + true, module->GetFlavor()); // Dump body } else { LogInfo::MapleLogger() << '\n'; } diff --git a/src/mapleall/maple_ir/src/mir_nodes.cpp b/src/mapleall/maple_ir/src/mir_nodes.cpp index 6885f4bfb1675da65abc9668c0b84c530d08b9a0..b20e80f88970ff4727ef8396cdbd35df32a67a80 100755 --- a/src/mapleall/maple_ir/src/mir_nodes.cpp +++ b/src/mapleall/maple_ir/src/mir_nodes.cpp @@ -766,7 +766,7 @@ void IassignFPoffNode::Dump(int32 indent) const { void BlkassignoffNode::Dump(int32 indent) const { StmtNode::DumpBase(indent); - LogInfo::MapleLogger() << " " << offset << " " << blockSize; + LogInfo::MapleLogger() << " " << offset << " " << GetAlign() << " " << blockSize; BinaryOpnds::Dump(indent); LogInfo::MapleLogger() << '\n'; } @@ -1201,8 +1201,8 @@ void CallinstantNode::Dump(int32 indent, bool newline) const { } } -void BlockNode::Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable *thePregTab, bool withInfo, - bool isFuncbody) const { +void BlockNode::Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable *thePregTab, + bool withInfo, bool isFuncbody, MIRFlavor flavor) const { if (!withInfo) { LogInfo::MapleLogger() << " {\n"; } @@ -1226,8 +1226,10 @@ void BlockNode::Dump(int32 indent, const MIRSymbolTable *theSymTab, MIRPregTable } } // print the locally declared variables - theSymTab->Dump(true, indent + 1); - thePregTab->DumpPregsWithTypes(indent + 1); + theSymTab->Dump(true/*isLocal*/, indent + 1, false/*printDeleted*/, flavor); + if (thePregTab != nullptr) { + thePregTab->DumpPregsWithTypes(indent + 1); + } } LogInfo::MapleLogger() << '\n'; if (theMIRModule->CurFunction()->NeedEmitAliasInfo()) { diff --git a/src/mapleall/maple_ir/src/mir_parser.cpp b/src/mapleall/maple_ir/src/mir_parser.cpp index 7181283181f741956b7cbe19a95fbf86bc4290d0..37daecc54a7d7dc088c4dafaac0df74774c966fb 100755 --- a/src/mapleall/maple_ir/src/mir_parser.cpp +++ b/src/mapleall/maple_ir/src/mir_parser.cpp @@ -247,6 +247,11 @@ bool MIRParser::ParseStmtBlkassignoff(StmtNodePtr &stmt) { return false; } bassignoff->offset = lexer.GetTheIntVal(); + if (lexer.NextToken() != TK_intconst) { + Error("expect align but get "); + return false; + } + bassignoff->SetAlign(lexer.GetTheIntVal()); if (lexer.NextToken() != TK_intconst) { Error("expect size but get "); return false; diff --git a/src/mapleall/maple_ir/src/mir_symbol.cpp b/src/mapleall/maple_ir/src/mir_symbol.cpp index 7a1134181fa2c900490cde1330cd3f88423fab3c..87f1caafd89df5675b3c75a9168ffb4a1ed240a0 100644 --- a/src/mapleall/maple_ir/src/mir_symbol.cpp +++ b/src/mapleall/maple_ir/src/mir_symbol.cpp @@ -393,7 +393,7 @@ const std::set MIRSymbol::staticFinalBlackList{ "Ljava_2Flang_2FSystem_3B_7Cin", }; -void MIRSymbolTable::Dump(bool isLocal, int32 indent, bool printDeleted) const { +void MIRSymbolTable::Dump(bool isLocal, int32 indent, bool printDeleted, MIRFlavor flavor) const { size_t size = symbolTable.size(); for (size_t i = 0; i < size; ++i) { MIRSymbol *symbol = symbolTable[i]; @@ -403,6 +403,9 @@ void MIRSymbolTable::Dump(bool isLocal, int32 indent, bool printDeleted) const { if (!printDeleted && symbol->IsDeleted()) { continue; } + if (flavor == kFlavorLmbc && symbol->LMBCAllocateOffSpecialReg()) { + continue; + } symbol->Dump(isLocal, indent, false /* suppressinit */, this); } } diff --git a/src/mapleall/maple_me/include/lmbc_lower.h b/src/mapleall/maple_me/include/lmbc_lower.h index 90145a49298ad285cba212117e6e973d1b80d937..90f056cfcbfe50c78c43d3b234d46bbad2aab835 100644 --- a/src/mapleall/maple_me/include/lmbc_lower.h +++ b/src/mapleall/maple_me/include/lmbc_lower.h @@ -34,16 +34,18 @@ class LMBCLowerer { mirModule(mod), func(f), becommon(becmmn), mirBuilder(mod->GetMIRBuilder()), globmemlayout(gmemlayout), memlayout(lmemlayout) {} - BaseNode *ReadregNodeForSymbol(MIRSymbol *); PregIdx GetSpecialRegFromSt(const MIRSymbol *); - BaseNode *LowerDread(AddrofNode *); BaseNode *LowerAddrof(AddrofNode *); + BaseNode *LowerDread(AddrofNode *); + BaseNode *LowerDreadoff(DreadoffNode *); BaseNode *LowerIread(IreadNode *); + BaseNode *LowerIaddrof(IreadNode *); BaseNode *LowerExpr(BaseNode *expr); - void LowerAggDassign(BlockNode *, const DassignNode *); + void LowerAggDassign(const DassignNode *, MIRType *lhsty, int32 offset, BlockNode *); void LowerDassign(DassignNode *, BlockNode *); + void LowerDassignoff(DassignoffNode *, BlockNode *); void LowerIassign(IassignNode *, BlockNode *); - void LowerAggIassign(BlockNode *, IassignNode *); + void LowerAggIassign(IassignNode *, MIRType *type, int32 offset, BlockNode *); void LowerReturn(NaryStmtNode *retNode, BlockNode *newblk); void LowerCall(NaryStmtNode *callNode, BlockNode *newblk); BlockNode *LowerBlock(BlockNode *); diff --git a/src/mapleall/maple_me/src/lmbc_lower.cpp b/src/mapleall/maple_me/src/lmbc_lower.cpp index 30c22ad26ea76e1e6616db95391f31f866db5d08..746fbeabc94e6d23440a5018f3ffb2470e74dd49 100644 --- a/src/mapleall/maple_me/src/lmbc_lower.cpp +++ b/src/mapleall/maple_me/src/lmbc_lower.cpp @@ -19,19 +19,6 @@ namespace maple { using namespace std; -inline PrimType UnsignedPrimType(int32 bytesize) { - if (bytesize == 4) { - return PTY_u32; - } - if (bytesize == 2) { - return PTY_u16; - } - if (bytesize == 1) { - return PTY_u8; - } - return PTY_u32; -} - PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { MIRStorageClass storageClass = sym->GetStorageClass(); PregIdx specreg = 0; @@ -55,29 +42,23 @@ PregIdx LMBCLowerer::GetSpecialRegFromSt(const MIRSymbol *sym) { return specreg; } -BaseNode *LMBCLowerer::ReadregNodeForSymbol(MIRSymbol *sym) { - return mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, GetSpecialRegFromSt(sym)); -} - BaseNode *LMBCLowerer::LowerAddrof(AddrofNode *expr) { MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(expr->GetStIdx()); - if (symbol->GetStorageClass() == kScText) { - return expr; - } int32 offset = 0; if (expr->GetFieldID() != 0) { MIRStructType *structty = dynamic_cast(symbol->GetType()); CHECK_FATAL(structty, "LMBCLowerer::LowerAddrof: non-zero fieldID for non-structure"); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; } - //BaseNode *rrn = ReadregNodeForSymbol(symbol); PrimType symty = (expr->GetPrimType() == PTY_simplestr || expr->GetPrimType() == PTY_simpleobj) ? expr->GetPrimType() : LOWERED_PTR_TYPE; + if (!symbol->LMBCAllocateOffSpecialReg()) { + return mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); + } BaseNode *rrn = mirBuilder->CreateExprRegread(symty, GetSpecialRegFromSt(symbol)); offset += symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()].offset : globmemlayout->sym_alloc_table[symbol->GetStIndex()].offset; return (offset == 0) ? rrn - : mirBuilder->CreateExprBinary(OP_add, *GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)expr->GetPrimType()), rrn, - mirBuilder->GetConstInt(offset)); + : mirBuilder->CreateExprBinary(OP_add, expr->GetPrimType(), rrn, mirBuilder->GetConstInt(offset)); } BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { @@ -91,7 +72,11 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { symty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first)->GetPrimType(); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; } - // allow dread class reference + if (!symbol->LMBCAllocateOffSpecialReg()) { + BaseNode *base = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, 0); + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(symty, offset, base); + return ireadoff; + } PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); @@ -107,6 +92,26 @@ BaseNode *LMBCLowerer::LowerDread(AddrofNode *expr) { } } +BaseNode *LMBCLowerer::LowerDreadoff(DreadoffNode *dreadoff) { + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dreadoff->stIdx); + if (!symbol->LMBCAllocateOffSpecialReg()) { + return dreadoff; + } + PregIdx spcreg = GetSpecialRegFromSt(symbol); + if (spcreg == -kSregFp) { + CHECK_FATAL(symbol->IsLocal(), "load from fp non local?"); + IreadFPoffNode *ireadoff = mirBuilder->CreateExprIreadFPoff( + dreadoff->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dreadoff->offset); + return ireadoff; + } else { + BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); + SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] + : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; + IreadoffNode *ireadoff = mirBuilder->CreateExprIreadoff(dreadoff->GetPrimType(), symalloc.offset + dreadoff->offset, rrn); + return ireadoff; + } +} + static MIRType *GetPointedToType(const MIRPtrType *pointerty) { MIRType *atype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx()); if (atype->GetKind() == kTypeArray) { @@ -122,400 +127,193 @@ static MIRType *GetPointedToType(const MIRPtrType *pointerty) { BaseNode *LMBCLowerer::LowerIread(IreadNode *expr) { int32 offset = 0; - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); - MIRPtrType *pointerty = static_cast(type); - CHECK_FATAL(pointerty, "expect a pointer type at iread node"); if (expr->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx())); - CHECK_FATAL(structty, "SelectIread: non-zero fieldID for non-structure"); - FieldPair thepair = structty->TraverseToField(expr->GetFieldID()); - type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); + MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(type)->GetPointedTyIdx())); + CHECK_FATAL(structty, "LowerIread: non-zero fieldID for non-structure"); offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; - } else { - type = GetPointedToType(pointerty); } - BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(type->GetPrimType(), offset, expr->Opnd(0)); + BaseNode *ireadoff = mirBuilder->CreateExprIreadoff(expr->GetPrimType(), offset, expr->Opnd(0)); return ireadoff; } +BaseNode *LMBCLowerer::LowerIaddrof(IaddrofNode *expr) { + int32 offset = 0; + if (expr->GetFieldID() != 0) { + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr->GetTyIdx()); + MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast(type)->GetPointedTyIdx())); + CHECK_FATAL(structty, "LowerIread: non-zero fieldID for non-structure"); + offset = becommon->GetFieldOffset(*structty, expr->GetFieldID()).first; + } + if (offset == 0) { + return expr->Opnd(0); + } + return mirBuilder->CreateExprBinary(OP_add, expr->GetPrimType(), expr->Opnd(0), mirBuilder->CreateIntConst(offset, expr->GetPrimType())); +} + BaseNode *LMBCLowerer::LowerExpr(BaseNode *expr) { for (size_t i = 0; i < expr->NumOpnds(); ++i) { expr->SetOpnd(LowerExpr(expr->Opnd(i)), i); } switch (expr->GetOpCode()) { - case OP_dread: return LowerDread(static_cast(expr)); case OP_addrof: return LowerAddrof(static_cast(expr)); + case OP_addrofoff: { + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(static_cast(expr)->stIdx); + CHECK_FATAL(!symbol->LMBCAllocateOffSpecialReg(), "LMBCLowerer:: illegal addrofoff instruction"); + break; + } + case OP_dread: return LowerDread(static_cast(expr)); + case OP_dreadoff: return LowerDreadoff(static_cast(expr)); case OP_iread: return LowerIread(static_cast(expr)); - default: ; + case OP_iaddrof: return LowerIaddrof(static_cast(expr)); + default: break; } return expr; } -void LMBCLowerer::LowerAggDassign(BlockNode *newblk, const DassignNode *dsnode) { - MIRSymbol *lhssymbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); - int32 lhsoffset = 0; - MIRType *lhsty = lhssymbol->GetType(); - if (dsnode->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(lhssymbol->GetType()); - CHECK_FATAL(structty, "LowerAggDassign: non-zero fieldID for non-structure"); - FieldPair thepair = structty->TraverseToField(dsnode->GetFieldID()); - lhsty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - lhsoffset = becommon->GetFieldOffset(*structty, dsnode->GetFieldID()).first; +// lower using OP_blkassignoff +void LMBCLowerer::LowerAggDassign(const DassignNode *dsnode, MIRType *lhsty, int32 offset, BlockNode *newblk) { + BaseNode *rhs = dsnode->Opnd(0); + CHECK_FATAL(rhs->GetOpCode() == OP_dread || rhs->GetOpCode() == OP_iread, "LowerAggDassign: rhs inconsistent"); + // change rhs to address of rhs + if (rhs->GetOpCode() == OP_dread) { + rhs->SetOpCode(OP_addrof); + } else { // OP_iread + rhs->SetOpCode(OP_iaddrof); } - uint32 lhsalign = becommon->GetTypeAlign(lhsty->GetTypeIndex()); - uint32 lhssize = becommon->GetTypeSize(lhsty->GetTypeIndex()); - - uint32 rhsalign; - uint32 alignused; - int32 rhsoffset = 0; - BaseNode *loadnode = nullptr; - IassignoffNode *iassignoff = nullptr; - if (dsnode->Opnd(0)->GetOpCode() == OP_dread) { - AddrofNode *rhsdread = static_cast(dsnode->Opnd(0)); - MIRSymbol *rhssymbol = func->GetLocalOrGlobalSymbol(rhsdread->GetStIdx()); - MIRType *rhsty = rhssymbol->GetType(); - if (rhsdread->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(rhssymbol->GetType()); - CHECK_FATAL(structty, "SelectDassign: non-zero fieldID for non-structure"); - FieldPair thepair = structty->TraverseToField(rhsdread->GetFieldID()); - rhsty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - rhsoffset = becommon->GetFieldOffset(*structty, rhsdread->GetFieldID()).first; - } - rhsalign = becommon->GetTypeAlign(rhsty->GetTypeIndex()); - BaseNode *rRrn = ReadregNodeForSymbol(rhssymbol); - SymbolAlloc &rsymalloc = rhssymbol->IsLocal() ? memlayout->sym_alloc_table[rhssymbol->GetStIndex()] - : globmemlayout->sym_alloc_table[rhssymbol->GetStIndex()]; - BaseNode *lRrn = ReadregNodeForSymbol(lhssymbol); - SymbolAlloc &lsymalloc = lhssymbol->IsLocal() ? memlayout->sym_alloc_table[lhssymbol->GetStIndex()] - : globmemlayout->sym_alloc_table[lhssymbol->GetStIndex()]; - - alignused = std::min(lhsalign, rhsalign); - alignused = std::min(alignused, 4u); // max alignment is 32-bit - if (!alignused) { - alignused = 1u; - } - for (uint32 i = 0; i < (lhssize / alignused); i++) { - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(alignused), - rsymalloc.offset + rhsoffset + i * alignused, rRrn); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff( - UnsignedPrimType(alignused), lsymalloc.offset + lhsoffset + i * alignused, lRrn, loadnode); - newblk->AddStatement(iassignoff); - } - // take care of extra content at the end less than the unit of alignused - uint32 lhssizeCovered = (lhssize / alignused) * alignused; - uint32 newalignused = alignused; - while (lhssizeCovered < lhssize) { - newalignused = newalignused >> 1; - if (lhssizeCovered + newalignused > lhssize) { - continue; - } - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(newalignused), - rsymalloc.offset + rhsoffset + lhssizeCovered, rRrn); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff( - UnsignedPrimType(newalignused), lsymalloc.offset + lhsoffset + lhssizeCovered, lRrn, loadnode); - newblk->AddStatement(iassignoff); - lhssizeCovered += newalignused; - } - } else if (dsnode->Opnd(0)->GetOpCode() == OP_regread) { - RegreadNode *regread = static_cast(dsnode->Opnd(0)); - CHECK_FATAL(regread->GetRegIdx() == -kSregRetval0 && regread->GetPrimType() == PTY_agg, ""); - - BaseNode *lRrn = ReadregNodeForSymbol(lhssymbol); - SymbolAlloc &lsymalloc = lhssymbol->IsLocal() ? memlayout->sym_alloc_table[lhssymbol->GetStIndex()] - : globmemlayout->sym_alloc_table[lhssymbol->GetStIndex()]; - - alignused = std::min(lhsalign, 4u); // max alignment is 32-bit - PregIdx ridx = -kSregRetval0; - for (uint32 i = 0; i < (lhssize / alignused); i++) { - // generate the load - loadnode = mirBuilder->CreateExprRegread(UnsignedPrimType(alignused), ridx - i); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff( - UnsignedPrimType(alignused), lsymalloc.offset + lhsoffset + i * alignused, lRrn, loadnode); - newblk->AddStatement(iassignoff); - } - // take care of extra content at the end less than the unit of alignused - uint32 lhssizeCovered = (lhssize / alignused) * alignused; - ridx = -kSregRetval0 - (lhssize / alignused); - uint32 newalignused = alignused; - while (lhssizeCovered < lhssize) { - newalignused = newalignused >> 1; - if (lhssizeCovered + newalignused > lhssize) { - continue; - } - // generate the load - loadnode = mirBuilder->CreateExprRegread(UnsignedPrimType(newalignused), ridx--); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff( - UnsignedPrimType(newalignused), lsymalloc.offset + lhsoffset + lhssizeCovered, lRrn, loadnode); - newblk->AddStatement(iassignoff); - lhssizeCovered += newalignused; - } - } else { // iread - IreadNode *rhsiread = static_cast(dsnode->Opnd(0)); - CHECK_FATAL(rhsiread, "LowerAggDassign: illegal rhs for dassign node of structure type"); - rhsiread->SetOpnd(LowerExpr(rhsiread->Opnd(0)), 0); - MIRType *rhsRdTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(rhsiread->GetTyIdx()); - MIRPtrType *pointerty = static_cast(rhsRdTy); - CHECK_FATAL(pointerty, "LowerAggDassign: expect a pointer type at iread node"); - if (rhsiread->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx())); - CHECK_FATAL(structty, "LowerAggDassign: non-zero fieldID for non-structure"); - FieldPair thepair = structty->TraverseToField(rhsiread->GetFieldID()); - rhsRdTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - rhsoffset = becommon->GetFieldOffset(*structty, rhsiread->GetFieldID()).first; - } else { - rhsRdTy = GetPointedToType(pointerty); - } - rhsalign = becommon->GetTypeAlign(rhsRdTy->GetTypeIndex()); - BaseNode *lRrn = ReadregNodeForSymbol(lhssymbol); - CHECK(lhssymbol->GetStIndex() < memlayout->sym_alloc_table.size() && - lhssymbol->GetStIndex() < globmemlayout->sym_alloc_table.size(), - "index oout of range in LMBCLowerer::LowerAggDassign"); - SymbolAlloc &lsymalloc = lhssymbol->IsLocal() ? memlayout->sym_alloc_table[lhssymbol->GetStIndex()] - : globmemlayout->sym_alloc_table[lhssymbol->GetStIndex()]; - - alignused = std::min(lhsalign, rhsalign); - alignused = std::min(alignused, 4u); // max alignment is 32-bit - for (uint32 i = 0; i < (lhssize / alignused); i++) { - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(alignused), rhsoffset + i * alignused, - rhsiread->Opnd(0)); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff( - UnsignedPrimType(alignused), lsymalloc.offset + lhsoffset + i * alignused, lRrn, loadnode); - newblk->AddStatement(iassignoff); - } - // take care of extra content at the end less than the unit of alignused - uint32 lhssizeCovered = (lhssize / alignused) * alignused; - uint32 newalignused = alignused; - while (lhssizeCovered < lhssize) { - newalignused = newalignused >> 1; - if (lhssizeCovered + newalignused > lhssize) { - continue; - } - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(newalignused), rhsoffset + lhssizeCovered, - rhsiread->Opnd(0)); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff( - UnsignedPrimType(newalignused), lsymalloc.offset + lhsoffset + lhssizeCovered, lRrn, loadnode); - newblk->AddStatement(iassignoff); - lhssizeCovered += newalignused; - } + rhs->SetPrimType(LOWERED_PTR_TYPE); + // generate lhs address expression + BaseNode *lhs = nullptr; + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + if (!symbol->LMBCAllocateOffSpecialReg()) { + lhs = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, offset); + } else { + lhs = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, GetSpecialRegFromSt(symbol)); + SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] + : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; + offset = symalloc.offset + offset; } + // generate the blkassignoff + BlkassignoffNode *bass = mirModule->CurFuncCodeMemPool()->New(offset, lhsty->GetSize()); + bass->SetAlign(lhsty->GetAlign()); + bass->SetBOpnd(lhs, 0); + bass->SetBOpnd(LowerExpr(rhs), 1); + newblk->AddStatement(bass); } void LMBCLowerer::LowerDassign(DassignNode *dsnode, BlockNode *newblk) { - if (dsnode->Opnd(0)->GetPrimType() != PTY_agg) { - dsnode->SetOpnd(LowerExpr(dsnode->Opnd(0)), 0); - MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); - int32 offset = 0; - PrimType ptypused = symbol->GetType()->GetPrimType(); - if (dsnode->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(symbol->GetType()); - CHECK_FATAL(structty, "LMBCLowerer::LowerDassign: non-zero fieldID for non-structure"); - offset = becommon->GetFieldOffset(*structty, dsnode->GetFieldID()).first; - TyIdx ftyidx = structty->TraverseToField(dsnode->GetFieldID()).second.first; - ptypused = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ftyidx)->GetPrimType(); + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->GetStIdx()); + MIRType *symty = symbol->GetType(); + int32 offset = 0; + if (dsnode->GetFieldID() != 0) { + MIRStructType *structty = dynamic_cast(symbol->GetType()); + CHECK_FATAL(structty, "LMBCLowerer::LowerDassign: non-zero fieldID for non-structure"); + FieldPair thepair = structty->TraverseToField(dsnode->GetFieldID()); + symty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); + offset = becommon->GetFieldOffset(*structty, dsnode->GetFieldID()).first; + } + BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); + if (rhs->GetPrimType() != PTY_agg || rhs->GetOpCode() == OP_regread) { + if (!symbol->LMBCAllocateOffSpecialReg()) { + BaseNode *base = mirBuilder->CreateExprDreadoff(OP_addrofoff, LOWERED_PTR_TYPE, *symbol, 0); + IassignoffNode *iassignoff = mirBuilder->CreateStmtIassignoff(symty->GetPrimType(), offset, base, rhs); + newblk->AddStatement(iassignoff); + return; } PregIdx spcreg = GetSpecialRegFromSt(symbol); if (spcreg == -kSregFp) { IassignFPoffNode *iassignoff = mirBuilder->CreateStmtIassignFPoff(OP_iassignfpoff, - ptypused, memlayout->sym_alloc_table[symbol->GetStIndex()].offset + offset, dsnode->Opnd(0)); + symty->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + offset, rhs); newblk->AddStatement(iassignoff); } else { - BaseNode *rrn = ReadregNodeForSymbol(symbol); + BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; IassignoffNode *iassignoff = - mirBuilder->CreateStmtIassignoff(ptypused, symalloc.offset + offset, rrn, dsnode->Opnd(0)); + mirBuilder->CreateStmtIassignoff(symty->GetPrimType(), symalloc.offset + offset, rrn, rhs); newblk->AddStatement(iassignoff); } } else { - LowerAggDassign(newblk, dsnode); + LowerAggDassign(dsnode, symty, offset, newblk); } } -void LMBCLowerer::LowerAggIassign(BlockNode *newblk, IassignNode *iassign) { - int32 lhsoffset = 0; - MIRType *lhsty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iassign->GetTyIdx()); - MIRPtrType *pointerty = static_cast(lhsty); - if (pointerty->GetKind() != kTypePointer) { - TypeAttrs typeAttrs; - pointerty = static_cast(GlobalTables::GetTypeTable().GetOrCreatePointerType(*lhsty, GetExactPtrPrimType(), typeAttrs)); +void LMBCLowerer::LowerDassignoff(DassignoffNode *dsnode, BlockNode *newblk) { + MIRSymbol *symbol = func->GetLocalOrGlobalSymbol(dsnode->stIdx); + CHECK_FATAL(dsnode->Opnd(0)->GetPrimType() != PTY_agg, "LowerDassignoff: agg primitive type NYI"); + BaseNode *rhs = LowerExpr(dsnode->Opnd(0)); + if (!symbol->LMBCAllocateOffSpecialReg()) { + newblk->AddStatement(dsnode); + return; } - if (iassign->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx())); - CHECK_FATAL(structty, "LowerAggDassign: non-zero fieldID for non-structure"); - FieldPair thepair = structty->TraverseToField(iassign->GetFieldID()); - lhsty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - lhsoffset = becommon->GetFieldOffset(*structty, iassign->GetFieldID()).first; + PregIdx spcreg = GetSpecialRegFromSt(symbol); + if (spcreg == -kSregFp) { + IassignFPoffNode *iassignoff = mirBuilder->CreateStmtIassignFPoff(OP_iassignfpoff, + dsnode->GetPrimType(), memlayout->sym_alloc_table[symbol->GetStIndex()].offset + dsnode->offset, rhs); + newblk->AddStatement(iassignoff); } else { - lhsty = GetPointedToType(pointerty); + BaseNode *rrn = mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, spcreg); + SymbolAlloc &symalloc = symbol->IsLocal() ? memlayout->sym_alloc_table[symbol->GetStIndex()] + : globmemlayout->sym_alloc_table[symbol->GetStIndex()]; + IassignoffNode *iassignoff = + mirBuilder->CreateStmtIassignoff(dsnode->GetPrimType(), symalloc.offset + dsnode->offset, rrn, rhs); + newblk->AddStatement(iassignoff); } - uint32 lhsalign = becommon->GetTypeAlign(lhsty->GetTypeIndex()); - uint32 lhssize = becommon->GetTypeSize(lhsty->GetTypeIndex()); - - uint32 rhsalign; - uint32 alignused; - int32 rhsoffset = 0; - BaseNode *loadnode = nullptr; - IassignoffNode *iassignoff = nullptr; - if (iassign->GetRHS()->GetOpCode() == OP_dread) { - AddrofNode *rhsdread = static_cast(iassign->GetRHS()); - MIRSymbol *rhssymbol = func->GetLocalOrGlobalSymbol(rhsdread->GetStIdx()); - MIRType *rhsty = rhssymbol->GetType(); - if (rhsdread->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(rhssymbol->GetType()); - CHECK_FATAL(structty, "SelectDassign: non-zero fieldID for non-structure"); - FieldPair thepair = structty->TraverseToField(rhsdread->GetFieldID()); - rhsty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - rhsoffset = becommon->GetFieldOffset(*structty, rhsdread->GetFieldID()).first; - } - rhsalign = becommon->GetTypeAlign(rhsty->GetTypeIndex()); - BaseNode *rRrn = ReadregNodeForSymbol(rhssymbol); - CHECK(rhssymbol->GetStIndex() < memlayout->sym_alloc_table.size() && - rhssymbol->GetStIndex() < globmemlayout->sym_alloc_table.size(), - "index out of range in LMBCLowerer::LowerAggIassign"); - SymbolAlloc &rsymalloc = rhssymbol->IsLocal() ? memlayout->sym_alloc_table[rhssymbol->GetStIndex()] - : globmemlayout->sym_alloc_table[rhssymbol->GetStIndex()]; - - alignused = std::min(lhsalign, rhsalign); - alignused = std::min(alignused, 4u); // max alignment is 32-bit - for (uint32 i = 0; i < (lhssize / alignused); i++) { - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(alignused), - rsymalloc.offset + rhsoffset + i * alignused, rRrn); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff(UnsignedPrimType(alignused), lhsoffset + i * alignused, - iassign->addrExpr, loadnode); - newblk->AddStatement(iassignoff); - } - // take care of extra content at the end less than the unit of alignused - uint32 lhssizeCovered = (lhssize / alignused) * alignused; - uint32 newalignused = alignused; - while (lhssizeCovered < lhssize) { - newalignused = newalignused >> 1; - if (lhssizeCovered + newalignused > lhssize) { - continue; - } - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(newalignused), - rsymalloc.offset + rhsoffset + lhssizeCovered, rRrn); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff(UnsignedPrimType(newalignused), - lhsoffset + lhssizeCovered, iassign->addrExpr, loadnode); - newblk->AddStatement(iassignoff); - lhssizeCovered += newalignused; - } - } else if (iassign->GetRHS()->GetOpCode() == OP_regread) { - RegreadNode *regread = static_cast(iassign->GetRHS()); - CHECK_FATAL(regread->GetRegIdx() == -kSregRetval0 && regread->GetPrimType() == PTY_agg, ""); - - alignused = std::min(lhsalign, 4u); // max alignment is 32-bit - PregIdx ridx = -kSregRetval0; - for (uint32 i = 0; i < (lhssize / alignused); i++) { - // generate the load - loadnode = mirBuilder->CreateExprRegread(UnsignedPrimType(alignused), ridx - i); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff(UnsignedPrimType(alignused), lhsoffset + i * alignused, - iassign->addrExpr, loadnode); - newblk->AddStatement(iassignoff); - } - // take care of extra content at the end less than the unit of alignused - uint32 lhssizeCovered = (lhssize / alignused) * alignused; - ridx = -kSregRetval0 - (lhssize / alignused); - uint32 newalignused = alignused; - while (lhssizeCovered < lhssize) { - newalignused = newalignused >> 1; - if (lhssizeCovered + newalignused > lhssize) { - continue; - } - // generate the load - loadnode = mirBuilder->CreateExprRegread(UnsignedPrimType(newalignused), ridx--); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff(UnsignedPrimType(newalignused), - lhsoffset + lhssizeCovered, iassign->addrExpr, loadnode); - newblk->AddStatement(iassignoff); - lhssizeCovered += newalignused; - } - } else { // iread - IreadNode *rhsiread = static_cast(iassign->GetRHS()); - CHECK_FATAL(rhsiread, "LowerAggIassign: illegal rhs for dassign node of structure type"); - rhsiread->SetOpnd(LowerExpr(rhsiread->Opnd(0)), 0); - MIRType *rhsRdTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(rhsiread->GetTyIdx()); - MIRPtrType *pointerty = static_cast(rhsRdTy); - CHECK_FATAL(pointerty, "LowerAggIassign: expect a pointer type at iread node"); - if (rhsiread->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx())); - CHECK_FATAL(structty, "LowerAggIassign: non-zero fieldID for non-structure"); - FieldPair thepair = structty->TraverseToField(rhsiread->GetFieldID()); - rhsRdTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(thepair.second.first); - rhsoffset = becommon->GetFieldOffset(*structty, rhsiread->GetFieldID()).first; - } else { - rhsRdTy = GetPointedToType(pointerty); - } - rhsalign = becommon->GetTypeAlign(rhsRdTy->GetTypeIndex()); +} - alignused = std::min(lhsalign, rhsalign); - alignused = std::min(alignused, 4u); // max alignment is 32-bit - for (uint32 i = 0; i < (lhssize / alignused); i++) { - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(alignused), rhsoffset + i * alignused, - rhsiread->Opnd(0)); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff(UnsignedPrimType(alignused), lhsoffset + i * alignused, - iassign->addrExpr, loadnode); - newblk->AddStatement(iassignoff); +// lower using OP_blkassignoff +void LMBCLowerer::LowerAggIassign(IassignNode *iassign, MIRType *lhsty, int32 offset, BlockNode *newblk) { + BaseNode *rhs = iassign->rhs; + CHECK_FATAL(rhs->GetOpCode() == OP_dread || rhs->GetOpCode() == OP_iread || + rhs->GetOpCode() == OP_ireadoff || rhs->GetOpCode() == OP_ireadfpoff, "LowerAggIassign: rhs inconsistent"); + // change rhs to address of rhs + switch (rhs->GetOpCode()) { + case OP_dread: rhs->SetOpCode(OP_addrof); break; + case OP_iread: rhs->SetOpCode(OP_iaddrof); break; + case OP_ireadoff: { + IreadoffNode *ireadoff = static_cast(rhs); + rhs = mirBuilder->CreateExprBinary(OP_add, LOWERED_PTR_TYPE, rhs->Opnd(0), mirBuilder->GetConstInt(ireadoff->GetOffset())); + break; } - // take care of extra content at the end less than the unit of alignused - uint32 lhssizeCovered = (lhssize / alignused) * alignused; - uint32 newalignused = alignused; - while (lhssizeCovered < lhssize) { - newalignused = newalignused >> 1; - if (lhssizeCovered + newalignused > lhssize) { - continue; - } - // generate the load - loadnode = mirBuilder->CreateExprIreadoff(UnsignedPrimType(newalignused), rhsoffset + lhssizeCovered, - rhsiread->Opnd(0)); - // generate the store - iassignoff = mirBuilder->CreateStmtIassignoff(UnsignedPrimType(newalignused), - lhsoffset + lhssizeCovered, iassign->addrExpr, loadnode); - newblk->AddStatement(iassignoff); - lhssizeCovered += newalignused; + case OP_ireadfpoff: { + IreadFPoffNode *ireadfpoff = static_cast(rhs); + rhs = mirBuilder->CreateExprBinary(OP_add, LOWERED_PTR_TYPE, mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregFp), mirBuilder->GetConstInt(ireadfpoff->GetOffset())); + break; } + default: ; } + rhs->SetPrimType(LOWERED_PTR_TYPE); + // generate the blkassignoff + BlkassignoffNode *bass = mirModule->CurFuncCodeMemPool()->New(offset, lhsty->GetSize()); + bass->SetAlign(lhsty->GetAlign()); + bass->SetBOpnd(iassign->addrExpr, 0); + bass->SetBOpnd(rhs, 1); + newblk->AddStatement(bass); } void LMBCLowerer::LowerIassign(IassignNode *iassign, BlockNode *newblk) { iassign->addrExpr = LowerExpr(iassign->Opnd(0)); + iassign->rhs = LowerExpr(iassign->GetRHS()); + int32 offset = 0; + MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iassign->GetTyIdx()); + MIRPtrType *pointerty = static_cast(type); + CHECK_FATAL(pointerty, "LowerIassign::expect a pointer type at iassign node"); + if (iassign->GetFieldID() != 0) { + MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx())); + CHECK_FATAL(structty, "LowerIassign: non-zero fieldID for non-structure"); + offset = becommon->GetFieldOffset(*structty, iassign->GetFieldID()).first; + TyIdx ftyidx = structty->TraverseToField(iassign->GetFieldID()).second.first; + type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ftyidx); + } else { + type = GetPointedToType(pointerty); + } if (iassign->GetRHS()->GetPrimType() != PTY_agg) { - iassign->SetRHS(LowerExpr(iassign->GetRHS())); - int32 offset = 0; - MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(iassign->GetTyIdx()); - MIRPtrType *pointerty = static_cast(type); - CHECK_FATAL(pointerty, "LowerIassign::expect a pointer type at iassign node"); - if (iassign->GetFieldID() != 0) { - MIRStructType *structty = dynamic_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(pointerty->GetPointedTyIdx())); - CHECK_FATAL(structty, "LowerAggIassign: non-zero fieldID for non-structure"); - offset = becommon->GetFieldOffset(*structty, iassign->GetFieldID()).first; - TyIdx ftyidx = structty->TraverseToField(iassign->GetFieldID()).second.first; - type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ftyidx); - } else { - type = GetPointedToType(pointerty); - } PrimType ptypused = type->GetPrimType(); IassignoffNode *iassignoff = - mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, iassign->GetRHS()); + mirBuilder->CreateStmtIassignoff(ptypused, offset, iassign->addrExpr, iassign->rhs); newblk->AddStatement(iassignoff); } else { - LowerAggIassign(newblk, iassign); + LowerAggIassign(iassign, type, offset, newblk); } } @@ -579,14 +377,16 @@ void LMBCLowerer::LowerCall(NaryStmtNode *naryStmt, BlockNode *newblk) { newblk->AddStatement(iass); } else { BlkassignoffNode *bass = mirModule->CurFuncCodeMemPool()->New(ploc.memoffset, ploc.memsize); - bass->SetBOpnd(mirBuilder->CreateExprRegread(PTY_a64, -kSregSp), 0); + bass->SetAlign(std::min(ty->GetAlign(), 8u)); + bass->SetBOpnd(mirBuilder->CreateExprRegread(LOWERED_PTR_TYPE, -kSregSp), 0); // the operand is either OP_dread or OP_iread; use its address instead if (opnd->GetOpCode() == OP_dread) { opnd->SetOpCode(OP_addrof); } else { opnd->SetOpCode(OP_iaddrof); } - bass->SetBOpnd(opnd, 1); + opnd->SetPrimType(LOWERED_PTR_TYPE); + bass->SetBOpnd(LowerExpr(opnd), 1); newblk->AddStatement(bass); } } @@ -622,6 +422,10 @@ BlockNode *LMBCLowerer::LowerBlock(BlockNode *block) { LowerDassign(static_cast(stmt), newblk); break; } + case OP_dassignoff: { + LowerDassignoff(static_cast(stmt), newblk); + break; + } case OP_iassign: { LowerIassign(static_cast(stmt), newblk); break; diff --git a/src/mapleall/maple_me/src/lmbc_memlayout.cpp b/src/mapleall/maple_me/src/lmbc_memlayout.cpp index f628e8d71fc084109543c64052c2825987fe9846..22df10601581a6c54bcca7d8857c9c5bfd59dea6 100644 --- a/src/mapleall/maple_me/src/lmbc_memlayout.cpp +++ b/src/mapleall/maple_me/src/lmbc_memlayout.cpp @@ -366,7 +366,7 @@ GlobalMemLayout::GlobalMemLayout(maplebe::BECommon *b, MIRModule *mod, MapleAll // starting from the beginning, one call per parameter in sequence; it returns // the information on how each parameter is passed in ploc void ParmLocator::LocateNextParm(const MIRType *ty, PLocInfo &ploc) { - ploc.memoffset = lastMemOffset; + ploc.memoffset = maplebe::RoundUp(lastMemOffset, 8); ploc.memsize = ty->GetSize(); uint32 rightpad = 0;