diff --git a/src/mapleall/maple_be/include/be/lower.h b/src/mapleall/maple_be/include/be/lower.h index 5585a496e1b8c934697271ba37e59df5621ef6f7..43e457e0274400d51c0ee09a4daec9e208a9ddc8 100644 --- a/src/mapleall/maple_be/include/be/lower.h +++ b/src/mapleall/maple_be/include/be/lower.h @@ -176,6 +176,8 @@ class CGLowerer { StmtNode *LowerDassignBitfield(DassignNode &dassign, BlockNode &block); StmtNode *LowerIassignBitfield(IassignNode &iassign, BlockNode &block); + void LowerAsmStmt(AsmNode *asmNode, BlockNode *blk); + bool ShouldOptarray() const { ASSERT(mirModule.CurFunction() != nullptr, "nullptr check"); return MIRLower::ShouldOptArrayMrt(*mirModule.CurFunction()); diff --git a/src/mapleall/maple_be/src/be/lower.cpp b/src/mapleall/maple_be/src/be/lower.cpp index e65758e88202272ee5a58278298f153770dd5340..16f80e8827448507af7feeb3734c5f37883137a4 100644 --- a/src/mapleall/maple_be/src/be/lower.cpp +++ b/src/mapleall/maple_be/src/be/lower.cpp @@ -1000,6 +1000,30 @@ void CGLowerer::LowerIassign(IassignNode &iassign, BlockNode &newBlk) { newBlk.AddStatement(newStmt); } +static GStrIdx NewAsmTempStrIdx() { + static uint32 strIdxCount = 0; // to create unique temporary symbol names + std::string asmTempStr("asm_tempvar"); + (void)asmTempStr.append(std::to_string(++strIdxCount)); + return GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(asmTempStr); +} + +void CGLowerer::LowerAsmStmt(AsmNode *asmNode, BlockNode *newBlk) { + for (size_t i = 0; i < asmNode->NumOpnds(); i++) { + BaseNode *opnd = LowerExpr(*asmNode, *asmNode->Opnd(i), *newBlk); + if (opnd->NumOpnds() == 0) { + asmNode->SetOpnd(opnd, i); + continue; + } + // introduce a temporary to store the expression tree operand + MIRSymbol *st = mirModule.GetMIRBuilder()->CreateSymbol((TyIdx)opnd->GetPrimType(), NewAsmTempStrIdx(), + kStVar, kScAuto, mirModule.CurFunction(), kScopeLocal); + DassignNode *dass = mirModule.GetMIRBuilder()->CreateStmtDassign(*st, 0, opnd); + newBlk->AddStatement(dass); + asmNode->SetOpnd(mirModule.GetMIRBuilder()->CreateExprDread(*st), i); + } + newBlk->AddStatement(asmNode); +} + DassignNode *CGLowerer::SaveReturnValueInLocal(StIdx stIdx, uint16 fieldID) { MIRSymbol *var; if (stIdx.IsGlobal()) { @@ -1559,6 +1583,10 @@ BlockNode *CGLowerer::LowerBlock(BlockNode &block) { LowerResetStmt(*stmt, *newBlk); break; } + case OP_asm: { + LowerAsmStmt(static_cast(stmt), newBlk); + break; + } default: LowerStmt(*stmt, *newBlk); newBlk->AddStatement(stmt);