comparison gen/naked.cpp @ 920:545f54041d91

Implemented proper support for naked asm using llvm module level asm. Still not 100% complete, but already 1000 times better that what we had before. Don's BignumX86 implementation from Tango (when turned into a standalone unittest) seems to fully work with no changes, and great performance :) Fixed align N; in asm blocks. Fixed inreg parameter passing on x86 for ref/out params. Removed support for lazy initialization of function local static variables, I have no idea why I ever implemented this, it's not in the D spec, and DMD doesn't support it :P Some of the global variable related changes might cause minor regressions, but they should be easily fixable.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 03 Feb 2009 08:54:57 +0100
parents
children 9bab304ed531
comparison
equal deleted inserted replaced
919:c76f74d09fb1 920:545f54041d91
1 #include "gen/llvm.h"
2
3 #include "expression.h"
4 #include "statement.h"
5 #include "declaration.h"
6
7 #include <cassert>
8
9 #include "gen/logger.h"
10 #include "gen/irstate.h"
11 #include "gen/llvmhelpers.h"
12
13 //////////////////////////////////////////////////////////////////////////////////////////
14
15 void Statement::toNakedIR(IRState *p)
16 {
17 error("not allowed in naked function");
18 }
19
20 //////////////////////////////////////////////////////////////////////////////////////////
21
22 void CompoundStatement::toNakedIR(IRState *p)
23 {
24 Logger::println("CompoundStatement::toNakedIR(): %s", loc.toChars());
25 LOG_SCOPE;
26
27 if (statements)
28 for (unsigned i = 0; i < statements->dim; i++)
29 {
30 Statement* s = (Statement*)statements->data[i];
31 if (s) s->toNakedIR(p);
32 }
33 }
34
35 //////////////////////////////////////////////////////////////////////////////////////////
36
37 void ExpStatement::toNakedIR(IRState *p)
38 {
39 Logger::println("ExpStatement::toNakedIR(): %s", loc.toChars());
40 LOG_SCOPE;
41
42 // only expstmt supported in declarations
43 if (exp->op != TOKdeclaration)
44 {
45 Statement::toNakedIR(p);
46 return;
47 }
48
49 DeclarationExp* d = (DeclarationExp*)exp;
50 VarDeclaration* vd = d->declaration->isVarDeclaration();
51 FuncDeclaration* fd = d->declaration->isFuncDeclaration();
52 EnumDeclaration* ed = d->declaration->isEnumDeclaration();
53
54 // and only static variable/function declaration
55 // no locals or nested stuffies!
56 if (!vd && !fd && !ed)
57 {
58 Statement::toNakedIR(p);
59 return;
60 }
61 else if (vd && !vd->isDataseg())
62 {
63 error("non-static variable '%s' not allowed in naked function", vd->toChars());
64 return;
65 }
66 else if (fd && !fd->isStatic())
67 {
68 error("non-static nested function '%s' not allowed in naked function", fd->toChars());
69 return;
70 }
71 // enum decls should always be safe
72
73 // make sure the symbols gets processed
74 d->declaration->toObjFile(0);
75 }
76
77 //////////////////////////////////////////////////////////////////////////////////////////
78
79 void LabelStatement::toNakedIR(IRState *p)
80 {
81 Logger::println("LabelStatement::toNakedIR(): %s", loc.toChars());
82 LOG_SCOPE;
83
84 p->nakedAsm << p->func()->decl->mangle() << "_" << ident->toChars() << ":";
85
86 if (statement)
87 statement->toNakedIR(p);
88 }
89
90 //////////////////////////////////////////////////////////////////////////////////////////
91
92 void DtoDefineNakedFunction(FuncDeclaration* fd)
93 {
94 Logger::println("DtoDefineNakedFunction(%s)", fd->mangle());
95 LOG_SCOPE;
96
97 assert(fd->ir.irFunc);
98 gIR->functions.push_back(fd->ir.irFunc);
99
100 // we need to do special processing on the body, since we only want
101 // to allow actual inline asm blocks to reach the final asm output
102
103 std::ostringstream& asmstr = gIR->nakedAsm;
104
105 // build function header
106
107 // REALLY FIXME: this is most likely extremely platform dependent
108
109 const char* mangle = fd->mangle();
110 const char* linkage = "globl";
111 std::string section = "text";
112 unsigned align = 16;
113
114 std::ostringstream tmpstr;
115
116 if (DtoIsTemplateInstance(fd))
117 {
118 linkage = "weak";
119 tmpstr << "section\t.gnu.linkonce.t." << mangle << ",\"ax\",@progbits";
120 section = tmpstr.str();
121 }
122
123 asmstr << "\t." << section << std::endl;
124 asmstr << "\t.align\t" << align << std::endl;
125 asmstr << "\t." << linkage << "\t" << mangle << std::endl;
126 asmstr << "\t.type\t" << mangle << ",@function" << std::endl;
127 asmstr << mangle << ":" << std::endl;
128
129 // emit body
130 fd->fbody->toNakedIR(gIR);
131
132 // emit size after body
133 // why? dunno, llvm seems to do it by default ..
134 asmstr << "\t.size\t" << mangle << ", .-" << mangle << std::endl << std::endl;
135
136 gIR->module->appendModuleInlineAsm(asmstr.str());
137 asmstr.str("");
138
139 gIR->functions.pop_back();
140 }