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 (IN_GCC)
27 {
28     import dmd.iasmgcc;
29 }
30 else
31 {
32     import dmd.iasmdmd;
33     version = MARS;
34 }
35 
36 /************************ AsmStatement ***************************************/
37 
38 extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc)
39 {
40     //printf("AsmStatement.semantic()\n");
41 
42     FuncDeclaration fd = sc.parent.isFuncDeclaration();
43     assert(fd);
44 
45     if (!s.tokens)
46         return null;
47 
48     // Assume assembler code takes care of setting the return value
49     sc.func.hasReturnExp |= 8;
50 
51     version (MARS)
52     {
53         /* If it starts with a string literal, it's gcc inline asm
54          */
55         if (s.tokens.value == TOK.string_)
56         {
57             /* Replace the asm statement with an assert(0, msg) that trips at runtime.
58              */
59             const loc = s.loc;
60             auto e = new IntegerExp(loc, 0, Type.tint32);
61             auto msg = new StringExp(loc, "Gnu Asm not supported - compile this function with gcc or clang");
62             auto ae = new AssertExp(loc, e, msg);
63             auto se = new ExpStatement(loc, ae);
64             return statementSemantic(se, sc);
65         }
66         auto ias = new InlineAsmStatement(s.loc, s.tokens);
67         ias.caseSensitive = s.caseSensitive;
68         return inlineAsmSemantic(ias, sc);
69     }
70     else version (IN_GCC)
71     {
72         auto eas = new GccAsmStatement(s.loc, s.tokens);
73         return gccAsmSemantic(eas, sc);
74     }
75     else
76     {
77         s.error("D inline assembler statements are not supported");
78         return new ErrorStatement();
79     }
80 }