1 /**
2  * Inline assembler for the D programming language compiler.
3  *
4  * Specification: $(LINK2 https://dlang.org/spec/iasm.html, Inline Assembler)
5  *
6  *              Copyright (C) 2018-2023 by The D Language Foundation, All Rights Reserved
7  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
8  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/iasm.d, _iasm.d)
10  * Documentation:  https://dlang.org/phobos/dmd_iasm.html
11  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/iasm.d
12  */
13 
14 module dmd.iasm;
15 
16 import core.stdc.stdio;
17 
18 import dmd.dscope;
19 import dmd.expression;
20 import dmd.func;
21 import dmd.mtype;
22 import dmd.tokens;
23 import dmd.statement;
24 import dmd.statementsem;
25 
26 version (MARS)
27 {
28     import dmd.iasmdmd;
29 }
30 else version (IN_GCC)
31 {
32     import dmd.iasmgcc;
33 }
34 
35 /************************ AsmStatement ***************************************/
36 
37 extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc)
38 {
39     //printf("AsmStatement.semantic()\n");
40 
41     FuncDeclaration fd = sc.parent.isFuncDeclaration();
42     assert(fd);
43 
44     if (!s.tokens)
45         return null;
46 
47     // Assume assembler code takes care of setting the return value
48     sc.func.hasReturnExp |= 8;
49 
50     version (MARS)
51     {
52         /* If it starts with a string literal, it's gcc inline asm
53          */
54         if (s.tokens.value == TOK.string_)
55         {
56             /* Replace the asm statement with an assert(0, msg) that trips at runtime.
57              */
58             const loc = s.loc;
59             auto e = new IntegerExp(loc, 0, Type.tint32);
60             auto msg = new StringExp(loc, "Gnu Asm not supported - compile this function with gcc or clang");
61             auto ae = new AssertExp(loc, e, msg);
62             auto se = new ExpStatement(loc, ae);
63             return statementSemantic(se, sc);
64         }
65         auto ias = new InlineAsmStatement(s.loc, s.tokens);
66         return inlineAsmSemantic(ias, sc);
67     }
68     else version (IN_GCC)
69     {
70         auto eas = new GccAsmStatement(s.loc, s.tokens);
71         return gccAsmSemantic(eas, sc);
72     }
73     else
74     {
75         s.error("D inline assembler statements are not supported");
76         return new ErrorStatement();
77     }
78 }