diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h index 9c51f64378e69815415de40d75516aa2090ccb91..1548a2c0d846bcef97572f8d06713ba4a47f2c16 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -95,6 +95,7 @@ class AArch64CGFunc : public CGFunc { void SelectIassign(IassignNode &stmt) override; void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) override; void SelectReturn(Operand *opnd0) override; + void SelectIgoto(Operand *opnd0) override; void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) override; void SelectCondGoto(LabelOperand &targetOpnd, Opcode jmpOp, Opcode cmpOp, Operand &opnd0, Operand &opnd1, PrimType primType); @@ -115,6 +116,7 @@ class AArch64CGFunc : public CGFunc { void SelectAddrof(Operand &result, AArch64MemOperand &memOpnd); Operand *SelectAddrof(AddrofNode &expr) override; Operand &SelectAddrofFunc(AddroffuncNode &expr) override; + Operand &SelectAddrofLabel(AddroflabelNode &expr) override; PrimType GetDestTypeFromAggSize(uint32 bitSize) const; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h index c22128ee7436357db6927711fa44fc80b1ed1156..8f85878bdec3b911167f3449413b6186a359fca1 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_insn.h @@ -163,6 +163,7 @@ class AArch64Insn : public Insn { void EmitAdrpLdr(const CG&, Emitter&) const; void EmitLazyBindingRoutine(Emitter&) const; void EmitClinitTail(Emitter&) const; + void EmitAdrpLabel(Emitter &) const; void EmitLazyLoad(Emitter&) const; void EmitLazyLoadStatic(Emitter&) const; void EmitArrayClassCacheLoad(Emitter&) const; diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.def index f1877d72aaedacac860b52ed44e98aa0e2535018..594965bc7c042cda90d1402e08617d6ab25b49bf 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_isa.def @@ -272,6 +272,7 @@ MOP_lazy_ldr, MOP_lazy_ldr_static, MOP_lazy_tail, MOP_adrp_ldr, +MOP_adrp_label, MOP_arrayclass_cache_ldr, MOP_clinit_tail, MOP_get_and_addI, diff --git a/src/mapleall/maple_be/include/cg/cgbb.h b/src/mapleall/maple_be/include/cg/cgbb.h index 58bd016ad66278ebfa030347b5460af9a1aeedde..6c350fde7067017628ad216be87301e7e4fe341b 100644 --- a/src/mapleall/maple_be/include/cg/cgbb.h +++ b/src/mapleall/maple_be/include/cg/cgbb.h @@ -75,6 +75,7 @@ class BB { kBBFallthru, /* default */ kBBIf, /* conditional branch */ kBBGoto, /* unconditional branch */ + kBBIgoto, kBBReturn, kBBIntrinsic, /* BB created by inlining intrinsics; shares a lot with BB_if */ kBBRangeGoto, diff --git a/src/mapleall/maple_be/include/cg/cgfunc.h b/src/mapleall/maple_be/include/cg/cgfunc.h index 3a5b68c62f0d632c91da285cde219941d84e1448..8a2cafb8ee8da79a5578cb46c60df0b0c31b4417 100644 --- a/src/mapleall/maple_be/include/cg/cgfunc.h +++ b/src/mapleall/maple_be/include/cg/cgfunc.h @@ -161,6 +161,7 @@ class CGFunc { virtual void SelectIassign(IassignNode &stmt) = 0; virtual void SelectAggIassign(IassignNode &stmt, Operand &lhsAddrOpnd) = 0; virtual void SelectReturn(Operand *opnd) = 0; + virtual void SelectIgoto(Operand *opnd0) = 0; virtual void SelectCondGoto(CondGotoNode &stmt, Operand &opnd0, Operand &opnd1) = 0; virtual void SelectCondSpecialCase1(CondGotoNode &stmt, BaseNode &opnd0) = 0; virtual void SelectCondSpecialCase2(const CondGotoNode &stmt, BaseNode &opnd0) = 0; @@ -177,6 +178,7 @@ class CGFunc { virtual RegOperand *SelectRegread(RegreadNode &expr) = 0; virtual Operand *SelectAddrof(AddrofNode &expr) = 0; virtual Operand &SelectAddrofFunc(AddroffuncNode &expr) = 0; + virtual Operand &SelectAddrofLabel(AddroflabelNode &expr) = 0; virtual Operand *SelectIread(const BaseNode &parent, IreadNode &expr) = 0; virtual Operand *SelectIntConst(MIRIntConst &intConst) = 0; virtual Operand *SelectFloatConst(MIRFloatConst &floatConst) = 0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index eb6d4105c95ae61d05e53cce9c89b84131e8de5a..5489cd883290dfca792fc9fa90f4263a265ef697 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -1525,6 +1525,14 @@ PrimType AArch64CGFunc::GetDestTypeFromAggSize(uint32 bitSize) const { return primType; } +Operand &AArch64CGFunc::SelectAddrofLabel(AddroflabelNode &expr) { + // adrp reg, label-id + Operand &dst = CreateVirtualRegisterOperand(NewVReg(kRegTyInt, expr.SizeOfInstr())); + Operand &immOpnd = CreateImmOperand(expr.GetOffset(), k64BitSize, false); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_adrp_label, dst, immOpnd)); + return dst; +} + Operand *AArch64CGFunc::SelectIread(const BaseNode &parent, IreadNode &expr) { int32 offset = 0; MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(expr.GetTyIdx()); @@ -1847,6 +1855,17 @@ bool AArch64CGFunc::GenerateCompareWithZeroInstruction(Opcode jmpOp, Opcode cmpO return finish; } +void AArch64CGFunc::SelectIgoto(Operand *opnd0) { + Operand *srcOpnd = opnd0; + if (opnd0->GetKind() == Operand::kOpdMem) { + Operand *dst = &CreateVirtualRegisterOperand(NewVReg(kRegTyInt, k8ByteSize)); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xldr, *dst, *opnd0)); + srcOpnd = dst; + } + GetCurBB()->SetKind(BB::kBBIgoto); + GetCurBB()->AppendInsn(GetCG()->BuildInstruction(MOP_xbr, *srcOpnd)); +} + void AArch64CGFunc::SelectCondGoto(LabelOperand &targetOpnd, Opcode jmpOp, Opcode cmpOp, Operand &origOpnd0, Operand &origOpnd1, PrimType primType) { Operand *opnd0 = &origOpnd0; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp index 030dc1dfcf02436d96cbf169ad030ee158168b69..c7fdae35fc7307b5d01174584090d48bdd42f326 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -724,6 +724,34 @@ void AArch64Insn::EmitAdrpLdr(const CG &cg, Emitter &emitter) const { emitter.Emit("]\n"); } +void AArch64Insn::EmitAdrpLabel(Emitter &emitter) const { + // adrp xd, label + // add xd, xd, #lo12:label + const AArch64MD *md = &AArch64CG::kMd[MOP_adrp_label]; + + Operand *opnd0 = opnds[0]; + Operand *opnd1 = opnds[1]; + OpndProp *prop0 = static_cast(md->operand[0]); + LabelIdx lidx = static_cast(opnd1)->GetValue(); + + // adrp xd, label + emitter.Emit("\t").Emit("adrp").Emit("\t"); + opnd0->Emit(emitter, prop0); + emitter.Emit(", "); + const char *idx; + idx = strdup(std::to_string(Globals::GetInstance()->GetBECommon()->GetMIRModule().CurFunction()->GetPuidx()).c_str()); + emitter.Emit(".label.").Emit(idx).Emit("__").Emit(lidx).Emit("\n"); + + // add xd, xd, #lo12:label + emitter.Emit("\tadd\t"); + opnd0->Emit(emitter, prop0); + emitter.Emit(", "); + opnd0->Emit(emitter, prop0); + emitter.Emit(", "); + emitter.Emit(":lo12:").Emit(".label.").Emit(idx).Emit("__").Emit(lidx).Emit("\n"); + emitter.Emit("\n"); +} + void AArch64Insn::EmitLazyBindingRoutine(Emitter &emitter) const { /* ldr xzr, [xs] */ const AArch64MD *md = &AArch64CG::kMd[MOP_adrp_ldr]; @@ -956,6 +984,10 @@ void AArch64Insn::Emit(const CG &cg, Emitter &emitter) const { emitter.IncreaseJavaInsnCount(kLazyLdrInsnCount); return; } + case MOP_adrp_label: { + EmitAdrpLabel(emitter); + return; + } case MOP_lazy_tail: { /* No need to emit this pseudo instruction. */ return; diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_md.def b/src/mapleall/maple_be/src/cg/aarch64/aarch64_md.def index f9b494c9a7f86cfffedd0911b3be93ed2fe1e067..1db55a798006232195ab223e7232cd735803d490 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_md.def +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_md.def @@ -668,6 +668,12 @@ */ {MOP_adrp_ldr, {mopdReg64ID, mopdLiteral},ISATOMIC|CANTHROW,kLtAdrpLdr,"intrinsic_adrpldr","0,1",2}, +/* will be emit to two instructions in a row: + * adrp xd, label + * add xd, xd, #:lo12:label + */ +{MOP_adrp_label, {mopdReg64ID, mopdImm64},0,kLtAlu,"intrinsic_adrplabel","0,1", 2}, + /* * will be emit to three instrunctions in a row: * adrp xd, :got:__arrayClassCacheTable$$xxx+offset diff --git a/src/mapleall/maple_be/src/cg/cg_cfg.cpp b/src/mapleall/maple_be/src/cg/cg_cfg.cpp index cb2d6da326bb860de6ece283d2e83a8d89086ac6..3a9d97b5a3ddc2deeb8c74d0dcbb7007cd8f386d 100644 --- a/src/mapleall/maple_be/src/cg/cg_cfg.cpp +++ b/src/mapleall/maple_be/src/cg/cg_cfg.cpp @@ -83,6 +83,15 @@ void CGCFG::BuildCFG() { gotoBB->PushBackPreds(*curBB); break; } + case BB::kBBIgoto: { + for (auto lidx : CG::GetCurCGFunc()->GetMirModule().CurFunction()->GetLabelTab()->GetAddrTakenLabels()) { + BB *igotobb = cgFunc->GetBBFromLab2BBMap(lidx); + CHECK_FATAL(igotobb, "igotobb is null"); + curBB->PushBackSuccs(*igotobb); + igotobb->PushBackPreds(*curBB); + } + break; + } case BB::kBBRangeGoto: { for (auto labelIdx : curBB->GetRangeGotoLabelVec()) { BB *gotoBB = cgFunc->GetBBFromLab2BBMap(labelIdx); diff --git a/src/mapleall/maple_be/src/cg/cgfunc.cpp b/src/mapleall/maple_be/src/cg/cgfunc.cpp index fe238da768136f30d45044e6699ad79b2b54c435..3857a14a298b7a858193fe9c754083fbb9b048b6 100644 --- a/src/mapleall/maple_be/src/cg/cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/cgfunc.cpp @@ -133,6 +133,12 @@ Operand *HandleAddroffunc(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc return &cgFunc.SelectAddrofFunc(addroffuncNode); } +Operand *HandleAddrofLabel(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) { + (void)parent; + auto &addrofLabelNode = static_cast(expr); + return &cgFunc.SelectAddrofLabel(addrofLabelNode); +} + Operand *HandleIread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc) { auto &ireadNode = static_cast(expr); return cgFunc.SelectIread(parent, ireadNode); @@ -340,6 +346,7 @@ void InitHandleExprFactory() { RegisterFactoryFunction(OP_rem, HandleRem); RegisterFactoryFunction(OP_addrof, HandleAddrof); RegisterFactoryFunction(OP_addroffunc, HandleAddroffunc); + RegisterFactoryFunction(OP_addroflabel, HandleAddrofLabel); RegisterFactoryFunction(OP_iread, HandleIread); RegisterFactoryFunction(OP_sub, HandleSub); RegisterFactoryFunction(OP_band, HandleBand); @@ -405,6 +412,13 @@ void HandleGoto(StmtNode &stmt, CGFunc &cgFunc) { } } +void HandleIgoto(StmtNode &stmt, CGFunc &cgFunc) { + auto &igotoNode = static_cast(stmt); + Operand *targetOpnd = cgFunc.HandleExpr(stmt, *igotoNode.Opnd(0)); + cgFunc.SelectIgoto(targetOpnd); + cgFunc.SetCurBB(*cgFunc.StartNewBB(igotoNode)); +} + void HandleCondbr(StmtNode &stmt, CGFunc &cgFunc) { auto &condGotoNode = static_cast(stmt); BaseNode *condNode = condGotoNode.Opnd(0); @@ -642,6 +656,7 @@ using HandleStmtFactory = FunctionFactory; void InitHandleStmtFactory() { RegisterFactoryFunction(OP_label, HandleLabel); RegisterFactoryFunction(OP_goto, HandleGoto); + RegisterFactoryFunction(OP_igoto, HandleIgoto); RegisterFactoryFunction(OP_brfalse, HandleCondbr); RegisterFactoryFunction(OP_brtrue, HandleCondbr); RegisterFactoryFunction(OP_return, HandleReturn); diff --git a/src/mapleall/maple_ir/include/mir_symbol.h b/src/mapleall/maple_ir/include/mir_symbol.h index 1dc50c613c799ca94f4a1e073d24568eff1a57bf..962c488336b6b90f2fe617070e91bc0a06e35839 100644 --- a/src/mapleall/maple_ir/include/mir_symbol.h +++ b/src/mapleall/maple_ir/include/mir_symbol.h @@ -597,6 +597,10 @@ class MIRLabelTable { return labelTable; } + MapleUnorderedSet GetAddrTakenLabels() { + return addrTakenLabels; + } + const MapleMap &GetStrIdxToLabelIdxMap() const { return strIdxToLabIdxMap; }