Skip to content

Commit 19a56a5

Browse files
committed
Alternative approach: Allow jumping to D labels in naked DMD-style inline-asm by making them asm labels too
1 parent 006e01b commit 19a56a5

3 files changed

Lines changed: 26 additions & 22 deletions

File tree

gen/asmstmt.cpp

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -532,10 +532,14 @@ void CompoundAsmStatement_toIR(CompoundAsmStatement *stmt, IRState *p) {
532532
}
533533
Identifier *const ident = targetLabel->ident;
534534

535-
// if the label is defined in inline asm, no special handling is necessary, skip
536-
if (fd->asmLabels && llvm::any_of(*fd->asmLabels, [ident](Identifier *i) {
537-
return i->equals(ident);
538-
})) {
535+
// if the label is defined in inline asm, we can jump to it directly
536+
if (fd->isNaked() // in naked DMD-style inline-asm functions, all D labels
537+
// become assembly labels too (and the extra forwarding
538+
// code would mess with the stack due to an i32 alloca)
539+
|| (fd->asmLabels &&
540+
llvm::any_of(*fd->asmLabels, [ident](Identifier *i) {
541+
return i->equals(ident);
542+
}))) {
539543
continue;
540544
}
541545

@@ -544,18 +548,6 @@ void CompoundAsmStatement_toIR(CompoundAsmStatement *stmt, IRState *p) {
544548
continue;
545549
}
546550

547-
// the extra forwarding code needs an i32 alloca, so messes with the stack
548-
if (fd->isNaked()) {
549-
error(stmt->loc,
550-
"branch to non-assembly D label `%s` not allowed in "
551-
"naked inline assembly",
552-
ident->toChars());
553-
errorSupplemental(
554-
stmt->loc,
555-
"Either define the label inside an `asm` block, or drop `naked`.");
556-
continue;
557-
}
558-
559551
// record that the jump needs to be handled in the post-asm dispatcher
560552
gotoToVal[targetLabel] = n_goto;
561553

gen/statements.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,15 +1542,20 @@ class ToIRVisitor : public Visitor {
15421542
auto &PGO = irs->funcGen().pgo;
15431543
PGO.setCurrentStmt(stmt);
15441544

1545+
auto fd = irs->func()->decl;
1546+
1547+
const auto getFullAsmLabelString = [stmt, fd]() {
1548+
std::stringstream s;
1549+
printLabelName(s, mangleExact(fd), stmt->ident->toChars());
1550+
s << ":";
1551+
return s.str();
1552+
};
1553+
15451554
// if it's an inline asm label, we don't create a basicblock, just emit it
15461555
// in the asm
15471556
if (irs->asmBlock) {
15481557
auto a = new IRAsmStmt;
1549-
std::stringstream label;
1550-
printLabelName(label, mangleExact(irs->func()->decl),
1551-
stmt->ident->toChars());
1552-
label << ":";
1553-
a->code = label.str();
1558+
a->code = getFullAsmLabelString();
15541559
irs->asmBlock->s.push_back(a);
15551560

15561561
// disable inlining
@@ -1565,6 +1570,13 @@ class ToIRVisitor : public Visitor {
15651570
}
15661571

15671572
irs->ir->SetInsertPoint(labelBB);
1573+
1574+
// in a naked DMD-style inline-asm function, create an assembly label too
1575+
// (so that inline-asm can jump to it directly)
1576+
if (fd->isNaked()) {
1577+
DtoInlineAsmExpr(stmt->loc, getFullAsmLabelString(), "", {}, {},
1578+
irs->ir->getVoidTy());
1579+
}
15681580
}
15691581

15701582
PGO.emitCounterIncrement(stmt);

runtime/phobos

0 commit comments

Comments
 (0)