annotate gen/asmstmt.cpp @ 1650:40bd4a0d4870

Update to work with LLVM 2.7. Removed use of dyn_cast, llvm no compiles without exceptions and rtti by default. We do need exceptions for the libconfig stuff, but rtti isn't necessary (anymore). Debug info needs to be rewritten, as in LLVM 2.7 the format has completely changed. To have something to look at while rewriting, the old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means that you have to define this to compile at the moment. Updated tango 0.99.9 patch to include updated EH runtime code, which is needed for LLVM 2.7 as well.
author Tomas Lindquist Olsen
date Wed, 19 May 2010 12:42:32 +0200
parents 8d086d552909
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
304
3ebc136702dd [svn r325] Removed dead code.
ChristianK
parents: 303
diff changeset
1 // Taken from GDC source tree. Original by David Friedman.
3ebc136702dd [svn r325] Removed dead code.
ChristianK
parents: 303
diff changeset
2 // Released under the Artistic License found in dmd/artistic.txt
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
3
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
4 #include "gen/llvm.h"
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
5 #include "llvm/InlineAsm.h"
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
6
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
7 //#include "d-gcc-includes.h"
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
8 //#include "total.h"
794
661384d6a936 Fix warnings on x86-64. By fvbommel.
Christian Kamm <kamm incasoftware de>
parents: 758
diff changeset
9 #include "mars.h"
758
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 756
diff changeset
10 #include "statement.h"
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 756
diff changeset
11 #include "scope.h"
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 756
diff changeset
12 #include "declaration.h"
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 756
diff changeset
13 #include "dsymbol.h"
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
14
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
15 #include <cassert>
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
16 #include <deque>
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
17 #include <cstring>
1102
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
18 #include <string>
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
19 #include <sstream>
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
20
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
21 //#include "d-lang.h"
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
22 //#include "d-codegen.h"
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
23
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
24 #include "gen/irstate.h"
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
25 #include "gen/dvalue.h"
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
26 #include "gen/tollvm.h"
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
27 #include "gen/logger.h"
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
28 #include "gen/todebug.h"
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
29 #include "gen/llvmhelpers.h"
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
30 #include "gen/functions.h"
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
31
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
32 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
33 Arg_Integer,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
34 Arg_Pointer,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
35 Arg_Memory,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
36 Arg_FrameRelative,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
37 Arg_LocalSize,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
38 Arg_Dollar
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
39 } AsmArgType;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
40
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
41 typedef enum {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
42 Mode_Input,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
43 Mode_Output,
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
44 Mode_Update
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
45 } AsmArgMode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
46
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
47 struct AsmArg {
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
48 Expression * expr;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
49 AsmArgType type;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
50 AsmArgMode mode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
51 AsmArg(AsmArgType type, Expression * expr, AsmArgMode mode) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
52 this->type = type;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
53 this->expr = expr;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
54 this->mode = mode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
55 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
56 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
57
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
58 struct AsmCode {
1102
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
59 std::string insnTemplate;
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
60 std::vector<AsmArg> args;
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
61 std::vector<bool> regs;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
62 unsigned dollarLabel;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
63 int clobbersMemory;
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
64 AsmCode(int n_regs) {
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
65 regs.resize(n_regs, false);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
66 dollarLabel = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
67 clobbersMemory = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
68 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
69 };
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
70
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
71 AsmStatement::AsmStatement(Loc loc, Token *tokens) :
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
72 Statement(loc)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
73 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
74 this->tokens = tokens; // Do I need to copy these?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
75 asmcode = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
76 asmalign = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
77 refparam = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
78 naked = 0;
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
79
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
80 isBranchToLabel = NULL;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
81 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
82
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
83 Statement *AsmStatement::syntaxCopy()
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
84 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
85 // copy tokens? copy 'code'?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
86 AsmStatement * a_s = new AsmStatement(loc,tokens);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
87 a_s->asmcode = asmcode;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
88 a_s->refparam = refparam;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
89 a_s->naked = naked;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
90 return a_s;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
91 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
92
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
93 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
94 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
95 bool sep = 0, nsep = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
96 buf->writestring("asm { ");
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
97
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
98 for (Token * t = tokens; t; t = t->next) {
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
99 switch (t->value) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
100 case TOKlparen:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
101 case TOKrparen:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
102 case TOKlbracket:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
103 case TOKrbracket:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
104 case TOKcolon:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
105 case TOKsemicolon:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
106 case TOKcomma:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
107 case TOKstring:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
108 case TOKcharv:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
109 case TOKwcharv:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
110 case TOKdcharv:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
111 nsep = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
112 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
113 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
114 nsep = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
115 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
116 if (sep + nsep == 2)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
117 buf->writeByte(' ');
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
118 sep = nsep;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
119 buf->writestring(t->toChars());
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
120 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
121 buf->writestring("; }");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
122 buf->writenl();
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
123 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
124
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
125 int AsmStatement::comeFrom()
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
126 {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
127 return FALSE;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
128 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
129
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
130 struct AsmParserCommon
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
131 {
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
132 virtual void run(Scope* sc, AsmStatement* asmst) = 0;
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
133 virtual std::string getRegName(int i) = 0;
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
134 };
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
135 AsmParserCommon* asmparser = NULL;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
136
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
137 #include "asm-x86-32.h"
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
138 #include "asm-x86-64.h"
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
139
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
140 bool d_have_inline_asm() { return true; }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
141
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
142 Statement *AsmStatement::semantic(Scope *sc)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
143 {
237
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
144 bool err = false;
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
145 if ((global.params.cpu != ARCHx86) && (global.params.cpu != ARCHx86_64))
237
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
146 {
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
147 error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch);
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
148 err = true;
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
149 }
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
150 if (!global.params.useInlineAsm)
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
151 {
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
152 error("inline asm is not allowed when the -noasm switch is used");
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
153 err = true;
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
154 }
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
155 if (err)
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
156 fatal();
a168a2c3ea48 [svn r253] Removed -inlineasm option. inline asm is now enabled by default unless the new -noasm option is passed.
lindquist
parents: 234
diff changeset
157
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
158 //puts(toChars());
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
159
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
160 sc->func->inlineAsm = 1;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
161 sc->func->inlineStatus = ILSno; // %% not sure
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
162 // %% need to set DECL_UNINLINABLE too?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
163 sc->func->hasReturnExp = 1; // %% DMD does this, apparently...
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
164
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
165 // empty statement -- still do the above things because they might be expected?
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
166 if (! tokens)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
167 return this;
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
168
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
169 if (!asmparser)
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
170 if (global.params.cpu == ARCHx86)
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
171 asmparser = new AsmParserx8632::AsmParser;
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
172 else if (global.params.cpu == ARCHx86_64)
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
173 asmparser = new AsmParserx8664::AsmParser;
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
174
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
175 asmparser->run(sc, this);
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
176
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
177 return this;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
178 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
179
336
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 312
diff changeset
180 int AsmStatement::blockExit()
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 312
diff changeset
181 {
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 312
diff changeset
182 //printf("AsmStatement::blockExit(%p)\n", this);
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 312
diff changeset
183 return BEfallthru | BEreturn | BEgoto | BEhalt;
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 312
diff changeset
184 }
aaade6ded589 [svn r357] Merged DMD 1.033
lindquist
parents: 312
diff changeset
185
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
186 void
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
187 AsmStatement::toIR(IRState * irs)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
188 {
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
189 Logger::println("AsmStatement::toIR(): %s", loc.toChars());
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
190 LOG_SCOPE;
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
191
533
2fe2d4518618 Reverted some changes in the Tango patch, splitting asm block is simply not supported by llvm.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 479
diff changeset
192 // sanity check
2fe2d4518618 Reverted some changes in the Tango patch, splitting asm block is simply not supported by llvm.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 479
diff changeset
193 assert(irs->func()->decl->inlineAsm);
2fe2d4518618 Reverted some changes in the Tango patch, splitting asm block is simply not supported by llvm.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 479
diff changeset
194
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
195 // get asm block
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
196 IRAsmBlock* asmblock = irs->asmBlock;
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
197 assert(asmblock);
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
198
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
199 #ifndef DISABLE_DEBUG_INFO
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
200 // debug info
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
201 if (global.params.symdebug)
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
202 DtoDwarfStopPoint(loc.linnum);
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
203 #endif
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
204
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
205 if (! asmcode)
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
206 return;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
207
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
208 static std::string i_cns = "i";
231
61aa721a6b7f [svn r247] fixed accessing global symbols from inline asm.
lindquist
parents: 229
diff changeset
209 static std::string p_cns = "i";
222
251548c1035d [svn r238] use *m for memory input constraints and pass in their address
ChristianK
parents: 221
diff changeset
210 static std::string m_cns = "*m";
221
68687d8c3e9a [svn r237] some inline asm output now seems to work, see tangotests/asm2.d
lindquist
parents: 220
diff changeset
211 static std::string mw_cns = "=*m";
223
5ffca623b5df [svn r239] also use indirect modifier for update constraints
ChristianK
parents: 222
diff changeset
212 static std::string mrw_cns = "+*m";
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
213 static std::string memory_name = "memory";
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
214
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
215 AsmCode * code = (AsmCode *) asmcode;
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
216 std::vector<LLValue*> input_values;
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
217 std::vector<std::string> input_constraints;
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
218 std::vector<LLValue*> output_values;
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
219 std::vector<std::string> output_constraints;
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
220 std::vector<std::string> clobbers;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
221
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
222 // FIXME
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
223 //#define HOST_WIDE_INT long
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
224 //HOST_WIDE_INT var_frame_offset; // "frame_offset" is a macro
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
225 bool clobbers_mem = code->clobbersMemory;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
226 int input_idx = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
227 int n_outputs = 0;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
228 int arg_map[10];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
229
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
230 assert(code->args.size() <= 10);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
231
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
232 std::vector<AsmArg>::iterator arg = code->args.begin();
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
233 for (unsigned i = 0; i < code->args.size(); i++, ++arg) {
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
234 bool is_input = true;
229
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
235 LLValue* arg_val = 0;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
236 std::string cns;
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
237
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
238 switch (arg->type) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
239 case Arg_Integer:
229
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
240 arg_val = arg->expr->toElem(irs)->getRVal();
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
241 do_integer:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
242 cns = i_cns;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
243 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
244 case Arg_Pointer:
234
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 233
diff changeset
245 assert(arg->expr->op == TOKvar);
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 233
diff changeset
246 arg_val = arg->expr->toElem(irs)->getRVal();
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 233
diff changeset
247 cns = p_cns;
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
248
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
249 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
250 case Arg_Memory:
229
cac3d27ae481 [svn r245] initial support for labels in inline asm, broken :/
lindquist
parents: 227
diff changeset
251 arg_val = arg->expr->toElem(irs)->getRVal();
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
252
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
253 switch (arg->mode) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
254 case Mode_Input: cns = m_cns; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
255 case Mode_Output: cns = mw_cns; is_input = false; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
256 case Mode_Update: cns = mrw_cns; is_input = false; break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
257 default: assert(0); break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
258 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
259 break;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
260 case Arg_FrameRelative:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
261 // FIXME
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
262 assert(0 && "asm fixme Arg_FrameRelative");
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
263 /* if (arg->expr->op == TOKvar)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
264 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
265 else
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
266 assert(0);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
267 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
268 // arg_val = irs->integerConstant(var_frame_offset);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
269 cns = i_cns;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
270 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
271 this->error("%s", "argument not frame relative");
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
272 return;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
273 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
274 if (arg->mode != Mode_Input)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
275 clobbers_mem = true;
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
276 break;*/
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
277 case Arg_LocalSize:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
278 // FIXME
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
279 assert(0 && "asm fixme Arg_LocalSize");
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
280 /* var_frame_offset = cfun->x_frame_offset;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
281 if (var_frame_offset < 0)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
282 var_frame_offset = - var_frame_offset;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
283 arg_val = irs->integerConstant( var_frame_offset );*/
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
284 goto do_integer;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
285 default:
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
286 assert(0);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
287 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
288
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
289 if (is_input) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
290 arg_map[i] = --input_idx;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
291 input_values.push_back(arg_val);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
292 input_constraints.push_back(cns);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
293 } else {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
294 arg_map[i] = n_outputs++;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
295 output_values.push_back(arg_val);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
296 output_constraints.push_back(cns);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
297 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
298 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
299
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
300 // Telling GCC that callee-saved registers are clobbered makes it preserve
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
301 // those registers. This changes the stack from what a naked function
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
302 // expects.
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
303
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
304 // FIXME
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
305 // if (! irs->func->naked) {
756
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
306 assert(asmparser);
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
307 for (int i = 0; i < code->regs.size(); i++) {
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
308 if (code->regs[i]) {
a58784e0f035 Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents: 622
diff changeset
309 clobbers.push_back(asmparser->getRegName(i));
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
310 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
311 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
312 if (clobbers_mem)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
313 clobbers.push_back(memory_name);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
314 // }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
315
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
316 // Remap argument numbers
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
317 for (unsigned i = 0; i < code->args.size(); i++) {
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
318 if (arg_map[i] < 0)
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
319 arg_map[i] = -arg_map[i] - 1 + n_outputs;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
320 }
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
321
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
322 bool pct = false;
1102
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
323 std::string::iterator
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
324 p = code->insnTemplate.begin(),
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
325 q = code->insnTemplate.end();
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
326 //printf("start: %.*s\n", code->insnTemplateLen, code->insnTemplate);
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
327 while (p < q) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
328 if (pct) {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
329 if (*p >= '0' && *p <= '9') {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
330 // %% doesn't check against nargs
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
331 *p = '0' + arg_map[*p - '0'];
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
332 pct = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
333 } else if (*p == '$') {
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
334 pct = false;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
335 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
336 //assert(*p == '%');// could be 'a', etc. so forget it..
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
337 } else if (*p == '$')
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
338 pct = true;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
339 ++p;
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
340 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
341
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
342 typedef std::vector<std::string>::iterator It;
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
343 if (Logger::enabled()) {
1102
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
344 Logger::cout() << "final asm: " << code->insnTemplate << '\n';
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
345 std::ostringstream ss;
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
346
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
347 ss << "GCC-style output constraints: {";
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
348 for (It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i) {
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
349 ss << " " << *i;
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
350 }
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
351 ss << " }";
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
352 Logger::println("%s", ss.str().c_str());
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
353
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
354 ss.str("");
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
355 ss << "GCC-style input constraints: {";
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
356 for (It i = input_constraints.begin(), e = input_constraints.end(); i != e; ++i) {
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
357 ss << " " << *i;
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
358 }
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
359 ss << " }";
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
360 Logger::println("%s", ss.str().c_str());
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
361
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
362 ss.str("");
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
363 ss << "GCC-style clobbers: {";
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
364 for (It i = clobbers.begin(), e = clobbers.end(); i != e; ++i) {
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
365 ss << " " << *i;
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
366 }
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
367 ss << " }";
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
368 Logger::println("%s", ss.str().c_str());
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
369 }
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
370
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
371 // rewrite GCC-style constraints to LLVM-style constraints
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
372 std::string llvmOutConstraints;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
373 std::string llvmInConstraints;
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
374 int n = 0;
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
375 for(It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i, ++n) {
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
376 // rewrite update constraint to in and out constraints
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
377 if((*i)[0] == '+') {
971
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
378 assert(*i == mrw_cns && "What else are we updating except memory?");
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
379 /* LLVM doesn't support updating operands, so split into an input
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
380 * and an output operand.
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
381 */
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
382
971
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
383 // Change update operand to pure output operand.
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
384 *i = mw_cns;
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
385
971
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
386 // Add input operand with same value, with original as "matching output".
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
387 std::ostringstream ss;
978
6a32d2e18175 Fix a latent bug in the asm code.
Frits van Bommel <fvbommel wxs.nl>
parents: 971
diff changeset
388 ss << '*' << (n + asmblock->outputcount);
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
389 // Must be at the back; unused operands before used ones screw up numbering.
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
390 input_constraints.push_back(ss.str());
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
391 input_values.push_back(output_values[n]);
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
392 }
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
393 llvmOutConstraints += *i;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
394 llvmOutConstraints += ",";
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
395 }
971
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
396 asmblock->outputcount += n;
985104c0f1db Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents: 969
diff changeset
397
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
398 for(It i = input_constraints.begin(), e = input_constraints.end(); i != e; ++i) {
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
399 llvmInConstraints += *i;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
400 llvmInConstraints += ",";
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
401 }
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
402
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
403 std::string clobstr;
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
404 for(It i = clobbers.begin(), e = clobbers.end(); i != e; ++i) {
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
405 clobstr = "~{" + *i + "},";
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
406 asmblock->clobs.insert(clobstr);
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
407 }
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
408
1053
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
409 if (Logger::enabled()) {
1101
8bf8b058944a Clean up asm code a bit.
Frits van Bommel <fvbommel wxs.nl>
parents: 1053
diff changeset
410 typedef std::vector<LLValue*>::iterator It;
1053
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
411 {
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
412 Logger::println("Output values:");
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
413 LOG_SCOPE
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
414 size_t i = 0;
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
415 for (It I = output_values.begin(), E = output_values.end(); I != E; ++I) {
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
416 Logger::cout() << "Out " << i++ << " = " << **I << '\n';
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
417 }
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
418 }
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
419 {
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
420 Logger::println("Input values:");
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
421 LOG_SCOPE
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
422 size_t i = 0;
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
423 for (It I = input_values.begin(), E = input_values.end(); I != E; ++I) {
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
424 Logger::cout() << "In " << i++ << " = " << **I << '\n';
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
425 }
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
426 }
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
427 }
11e28922ac76 Always pass an address expression (not a var expression) to asm operands of
Frits van Bommel <fvbommel wxs.nl>
parents: 1037
diff changeset
428
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
429 // excessive commas are removed later...
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
430
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
431 // push asm statement
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
432 IRAsmStmt* asmStmt = new IRAsmStmt;
1102
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
433 asmStmt->code = code->insnTemplate;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
434 asmStmt->out_c = llvmOutConstraints;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
435 asmStmt->in_c = llvmInConstraints;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
436 asmStmt->out.insert(asmStmt->out.begin(), output_values.begin(), output_values.end());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
437 asmStmt->in.insert(asmStmt->in.begin(), input_values.begin(), input_values.end());
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
438 asmStmt->isBranchToLabel = isBranchToLabel;
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
439 asmblock->s.push_back(asmStmt);
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
440 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
441
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
442 //////////////////////////////////////////////////////////////////////////////
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
443
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
444 AsmBlockStatement::AsmBlockStatement(Loc loc, Statements* s)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
445 : CompoundStatement(loc, s)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
446 {
1141
f99a3b393c03 Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents: 1103
diff changeset
447 enclosingFinally = NULL;
f99a3b393c03 Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents: 1103
diff changeset
448 enclosingScopeExit = NULL;
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
449
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
450 abiret = NULL;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
451 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
452
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
453 // rewrite argument indices to the block scope indices
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
454 static void remap_outargs(std::string& insnt, size_t nargs, size_t idx)
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
455 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
456 static const std::string digits[10] =
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
457 {
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
458 "0","1","2","3","4",
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
459 "5","6","7","8","9"
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
460 };
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
461 assert(nargs <= 10);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
462
234
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 233
diff changeset
463 static const std::string prefix("<<out");
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 233
diff changeset
464 static const std::string suffix(">>");
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
465 std::string argnum;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
466 std::string needle;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
467 char buf[10];
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
468 for (unsigned i = 0; i < nargs; i++) {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
469 needle = prefix + digits[i] + suffix;
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
470 size_t pos = insnt.find(needle);
303
4aa2b6753059 [svn r324] Small indentation fixes.
ChristianK
parents: 302
diff changeset
471 if(std::string::npos != pos)
1103
b30fe7e1dbb9 - Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents: 1102
diff changeset
472 sprintf(buf, "%lu", idx++);
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
473 while(std::string::npos != (pos = insnt.find(needle)))
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
474 insnt.replace(pos, needle.size(), buf);
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
475 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
476 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
477
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
478 // rewrite argument indices to the block scope indices
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
479 static void remap_inargs(std::string& insnt, size_t nargs, size_t idx)
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
480 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
481 static const std::string digits[10] =
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
482 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
483 "0","1","2","3","4",
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
484 "5","6","7","8","9"
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
485 };
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
486 assert(nargs <= 10);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
487
234
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 233
diff changeset
488 static const std::string prefix("<<in");
9760f54af0b7 [svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents: 233
diff changeset
489 static const std::string suffix(">>");
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
490 std::string argnum;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
491 std::string needle;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
492 char buf[10];
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
493 for (unsigned i = 0; i < nargs; i++) {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
494 needle = prefix + digits[i] + suffix;
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
495 size_t pos = insnt.find(needle);
303
4aa2b6753059 [svn r324] Small indentation fixes.
ChristianK
parents: 302
diff changeset
496 if(std::string::npos != pos)
1103
b30fe7e1dbb9 - Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents: 1102
diff changeset
497 sprintf(buf, "%lu", idx++);
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
498 while(std::string::npos != (pos = insnt.find(needle)))
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
499 insnt.replace(pos, needle.size(), buf);
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
500 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
501 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
502
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
503 LLValue* DtoAggrPairSwap(LLValue* aggr);
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
504
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
505 void AsmBlockStatement::toIR(IRState* p)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
506 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
507 Logger::println("AsmBlockStatement::toIR(): %s", loc.toChars());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
508 LOG_SCOPE;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
509 Logger::println("BEGIN ASM");
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
510
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
511 // disable inlining by default
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
512 if (!p->func()->decl->allowInlining)
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
513 p->func()->setNeverInline();
584
c7d7e2282ba3 Make sure functions containing inline asm are never inlined to avoid
Christian Kamm <kamm incasoftware de>
parents: 533
diff changeset
514
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
515 // create asm block structure
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
516 assert(!p->asmBlock);
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
517 IRAsmBlock* asmblock = new IRAsmBlock(this);
239
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
518 assert(asmblock);
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
519 p->asmBlock = asmblock;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
520
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
521 // do asm statements
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
522 for (int i=0; i<statements->dim; i++)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
523 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
524 Statement* s = (Statement*)statements->data[i];
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
525 if (s) {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
526 s->toIR(p);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
527 }
220
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
528 }
ccc2e6898a78 [svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents: 219
diff changeset
529
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
530 // build forwarder for in-asm branches to external labels
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
531 // this additional asm code sets the __llvm_jump_target variable
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
532 // to a unique value that will identify the jump target in
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
533 // a post-asm switch
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
534
312
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
535 // maps each goto destination to its special value
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
536 std::map<Identifier*, int> gotoToVal;
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
537
312
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
538 // location of the special value determining the goto label
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
539 // will be set if post-asm dispatcher block is needed
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
540 llvm::AllocaInst* jump_target;
301
f42a1090e895 [svn r322] More asm-to-outside jumping work. Unfinished.
ChristianK
parents: 300
diff changeset
541
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
542 {
305
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
543 FuncDeclaration* fd = gIR->func()->decl;
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
544 char* fdmangle = fd->mangle();
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
545
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
546 // we use a simple static counter to make sure the new end labels are unique
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
547 static size_t uniqueLabelsId = 0;
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
548 std::ostringstream asmGotoEndLabel;
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
549 asmGotoEndLabel << "." << fdmangle << "__llvm_asm_end" << uniqueLabelsId++;
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
550
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
551 // initialize the setter statement we're going to build
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
552 IRAsmStmt* outSetterStmt = new IRAsmStmt;
980
ae710cba0884 Clean up the code generated when jumping out of inline asm and make label names more expressive.
Frits van Bommel <fvbommel wxs.nl>
parents: 979
diff changeset
553 std::string asmGotoEnd = "\n\tjmp "+asmGotoEndLabel.str()+"\n";
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
554 std::ostringstream code;
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
555 code << asmGotoEnd;
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
556
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
557 int n_goto = 1;
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
558
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
559 size_t n = asmblock->s.size();
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
560 for(size_t i=0; i<n; ++i)
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
561 {
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
562 IRAsmStmt* a = asmblock->s[i];
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
563
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
564 // skip non-branch statements
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
565 if(!a->isBranchToLabel)
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
566 continue;
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
567
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
568 // if internal, no special handling is necessary, skip
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
569 std::vector<Identifier*>::const_iterator it, end;
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
570 end = asmblock->internalLabels.end();
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
571 bool skip = false;
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
572 for(it = asmblock->internalLabels.begin(); it != end; ++it)
305
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
573 if((*it)->equals(a->isBranchToLabel))
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
574 skip = true;
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1571
diff changeset
575 if(skip)
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
576 continue;
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
577
312
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
578 // if we already set things up for this branch target, skip
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
579 if(gotoToVal.find(a->isBranchToLabel) != gotoToVal.end())
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
580 continue;
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
581
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
582 // record that the jump needs to be handled in the post-asm dispatcher
312
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
583 gotoToVal[a->isBranchToLabel] = n_goto;
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
584
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
585 // provide an in-asm target for the branch and set value
305
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
586 Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string);
980
ae710cba0884 Clean up the code generated when jumping out of inline asm and make label names more expressive.
Frits van Bommel <fvbommel wxs.nl>
parents: 979
diff changeset
587 code << fdmangle << '_' << a->isBranchToLabel->string << ":\n\t";
ae710cba0884 Clean up the code generated when jumping out of inline asm and make label names more expressive.
Frits van Bommel <fvbommel wxs.nl>
parents: 979
diff changeset
588 code << "movl $<<in" << n_goto << ">>, $<<out0>>\n";
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
589 //FIXME: Store the value -> label mapping somewhere, so it can be referenced later
305
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
590 outSetterStmt->in.push_back(DtoConstUint(n_goto));
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
591 outSetterStmt->in_c += "i,";
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
592 code << asmGotoEnd;
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
593
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
594 ++n_goto;
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
595 }
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
596 if(code.str() != asmGotoEnd)
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
597 {
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
598 // finalize code
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
599 outSetterStmt->code = code.str();
980
ae710cba0884 Clean up the code generated when jumping out of inline asm and make label names more expressive.
Frits van Bommel <fvbommel wxs.nl>
parents: 979
diff changeset
600 outSetterStmt->code += asmGotoEndLabel.str()+":\n";
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
601
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
602 // create storage for and initialize the temporary
1350
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1160
diff changeset
603 jump_target = DtoAlloca(Type::tint32, "__llvm_jump_target");
305
2b72433d5c8c [svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents: 304
diff changeset
604 gIR->ir->CreateStore(DtoConstUint(0), jump_target);
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
605 // setup variable for output from asm
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
606 outSetterStmt->out_c = "=*m,";
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
607 outSetterStmt->out.push_back(jump_target);
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
608
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
609 asmblock->s.push_back(outSetterStmt);
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
610 }
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
611 else
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
612 delete outSetterStmt;
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
613 }
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
614
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
615
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
616 // build a fall-off-end-properly asm statement
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
617
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
618 FuncDeclaration* thisfunc = p->func()->decl;
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
619 bool useabiret = false;
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
620 p->asmBlock->asmBlock->abiret = NULL;
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
621 if (thisfunc->fbody->endsWithAsm() == this && thisfunc->type->nextOf()->ty != Tvoid)
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
622 {
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
623 // there can't be goto forwarders in this case
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
624 assert(gotoToVal.empty());
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
625 emitABIReturnAsmStmt(asmblock, loc, thisfunc);
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
626 useabiret = true;
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
627 }
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
628
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
629
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
630 // build asm block
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
631 std::vector<LLValue*> outargs;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
632 std::vector<LLValue*> inargs;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
633 std::vector<const LLType*> outtypes;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
634 std::vector<const LLType*> intypes;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
635 std::string out_c;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
636 std::string in_c;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
637 std::string clobbers;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
638 std::string code;
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
639 size_t asmIdx = asmblock->retn;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
640
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
641 Logger::println("do outputs");
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
642 size_t n = asmblock->s.size();
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
643 for (size_t i=0; i<n; ++i)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
644 {
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
645 IRAsmStmt* a = asmblock->s[i];
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
646 assert(a);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
647 size_t onn = a->out.size();
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
648 for (size_t j=0; j<onn; ++j)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
649 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
650 outargs.push_back(a->out[j]);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
651 outtypes.push_back(a->out[j]->getType());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
652 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
653 if (!a->out_c.empty())
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
654 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
655 out_c += a->out_c;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
656 }
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
657 remap_outargs(a->code, onn+a->in.size(), asmIdx);
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
658 asmIdx += onn;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
659 }
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
660
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
661 Logger::println("do inputs");
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
662 for (size_t i=0; i<n; ++i)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
663 {
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
664 IRAsmStmt* a = asmblock->s[i];
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
665 assert(a);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
666 size_t inn = a->in.size();
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
667 for (size_t j=0; j<inn; ++j)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
668 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
669 inargs.push_back(a->in[j]);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
670 intypes.push_back(a->in[j]->getType());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
671 }
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
672 if (!a->in_c.empty())
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
673 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
674 in_c += a->in_c;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
675 }
300
7b1040c76dd2 [svn r321] Fix bug in argument remapping functions.
ChristianK
parents: 299
diff changeset
676 remap_inargs(a->code, inn+a->out.size(), asmIdx);
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
677 asmIdx += inn;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
678 if (!code.empty())
954
e048e36bc155 Added support for using a temporary to implement emulated ABI return from inline asm, could be easier to use, but I think this will do. It's so extremely target dependent in any case that doing a completely generic approach seems hard.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 945
diff changeset
679 code += "\n\t";
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
680 code += a->code;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
681 }
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
682 asmblock->s.clear();
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
683
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
684 // append inputs
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
685 out_c += in_c;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
686
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
687 // append clobbers
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
688 typedef std::set<std::string>::iterator clobs_it;
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
689 for (clobs_it i=asmblock->clobs.begin(); i!=asmblock->clobs.end(); ++i)
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
690 {
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
691 out_c += *i;
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
692 }
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
693
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
694 // remove excessive comma
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
695 if (!out_c.empty())
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
696 out_c.resize(out_c.size()-1);
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
697
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
698 Logger::println("code = \"%s\"", code.c_str());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
699 Logger::println("constraints = \"%s\"", out_c.c_str());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
700
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
701 // build return types
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
702 const LLType* retty;
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
703 if (asmblock->retn)
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
704 retty = asmblock->retty;
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
705 else
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
706 retty = llvm::Type::getVoidTy(gIR->context());
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
707
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
708 // build argument types
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
709 std::vector<const LLType*> types;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
710 types.insert(types.end(), outtypes.begin(), outtypes.end());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
711 types.insert(types.end(), intypes.begin(), intypes.end());
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
712 llvm::FunctionType* fty = llvm::FunctionType::get(retty, types, false);
622
26fce59fe80a Wrapped all the most potentially expensive logging calls in a conditional to only do work when actually requested.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 584
diff changeset
713 if (Logger::enabled())
26fce59fe80a Wrapped all the most potentially expensive logging calls in a conditional to only do work when actually requested.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 584
diff changeset
714 Logger::cout() << "function type = " << *fty << '\n';
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
715
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
716 std::vector<LLValue*> args;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
717 args.insert(args.end(), outargs.begin(), outargs.end());
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
718 args.insert(args.end(), inargs.begin(), inargs.end());
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
719
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
720 if (Logger::enabled()) {
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
721 Logger::cout() << "Arguments:" << '\n';
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
722 Logger::indent();
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
723 for (std::vector<LLValue*>::iterator b = args.begin(), i = b, e = args.end(); i != e; ++i) {
1502
2292878925f4 Add an `llvm::OStream` workalike class for use with `Logger::cout()`, with the
Frits van Bommel <fvbommel wxs.nl>
parents: 1350
diff changeset
724 Stream cout = Logger::cout();
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
725 cout << '$' << (i - b) << " ==> " << **i;
995
125c09006ac6 Fix some -vv output
Frits van Bommel <fvbommel wxs.nl>
parents: 994
diff changeset
726 if (!llvm::isa<llvm::Instruction>(*i) && !llvm::isa<LLGlobalValue>(*i))
979
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
727 cout << '\n';
523bf4f166bc Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents: 978
diff changeset
728 }
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
729 Logger::undent();
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
730 }
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
731
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
732 llvm::InlineAsm* ia = llvm::InlineAsm::get(fty, code, out_c, true);
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
733
959
7e669954db7d Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents: 954
diff changeset
734 llvm::CallInst* call = p->ir->CreateCall(ia, args.begin(), args.end(),
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
735 retty == LLType::getVoidTy(gIR->context()) ? "" : "asm");
954
e048e36bc155 Added support for using a temporary to implement emulated ABI return from inline asm, could be easier to use, but I think this will do. It's so extremely target dependent in any case that doing a completely generic approach seems hard.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 945
diff changeset
736
969
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
737 if (Logger::enabled())
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
738 Logger::cout() << "Complete asm statement: " << *call << '\n';
fe2d9bb7078d Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents: 959
diff changeset
739
954
e048e36bc155 Added support for using a temporary to implement emulated ABI return from inline asm, could be easier to use, but I think this will do. It's so extremely target dependent in any case that doing a completely generic approach seems hard.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 945
diff changeset
740 // capture abi return value
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
741 if (useabiret)
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
742 {
959
7e669954db7d Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents: 954
diff changeset
743 IRAsmBlock* block = p->asmBlock;
7e669954db7d Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents: 954
diff changeset
744 if (block->retfixup)
7e669954db7d Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents: 954
diff changeset
745 block->asmBlock->abiret = (*block->retfixup)(p->ir, call);
7e669954db7d Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents: 954
diff changeset
746 else if (p->asmBlock->retemu)
7e669954db7d Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents: 954
diff changeset
747 block->asmBlock->abiret = DtoLoad(block->asmBlock->abiret);
954
e048e36bc155 Added support for using a temporary to implement emulated ABI return from inline asm, could be easier to use, but I think this will do. It's so extremely target dependent in any case that doing a completely generic approach seems hard.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 945
diff changeset
748 else
959
7e669954db7d Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents: 954
diff changeset
749 block->asmBlock->abiret = call;
945
03d7c4aac654 SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 920
diff changeset
750 }
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
751
233
76ee1bbe487e [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
lindquist
parents: 232
diff changeset
752 p->asmBlock = NULL;
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
753 Logger::println("END ASM");
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
754
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
755 // if asm contained external branches, emit goto forwarder code
312
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
756 if(!gotoToVal.empty())
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
757 {
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
758 assert(jump_target);
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
759
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
760 // make new blocks
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
761 llvm::BasicBlock* oldend = gIR->scopeend();
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
762 llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "afterasmgotoforwarder", p->topfunc(), oldend);
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
763
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
764 llvm::LoadInst* val = p->ir->CreateLoad(jump_target, "__llvm_jump_target_value");
312
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
765 llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size());
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
766
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
767 // add all cases
312
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
768 std::map<Identifier*, int>::iterator it, end = gotoToVal.end();
553f844ae5b9 [svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents: 309
diff changeset
769 for(it = gotoToVal.begin(); it != end; ++it)
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
770 {
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
771 llvm::BasicBlock* casebb = llvm::BasicBlock::Create(gIR->context(), "case", p->topfunc(), bb);
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
772 sw->addCase(LLConstantInt::get(llvm::IntegerType::get(gIR->context(), 32), it->second), casebb);
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
773
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
774 p->scope() = IRScope(casebb,bb);
1160
7d28dcbff23e Reenable error for gotos into or out of finally blocks.
Christian Kamm <kamm incasoftware de>
parents: 1141
diff changeset
775 DtoGoto(loc, it->first, enclosingFinally);
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
776 }
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
777
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
778 p->scope() = IRScope(bb,oldend);
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
779 }
219
761c8352f494 [svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff changeset
780 }
232
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
781
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
782 // the whole idea of this statement is to avoid the flattening
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
783 Statements* AsmBlockStatement::flatten(Scope* sc)
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
784 {
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
785 return NULL;
092468448d25 [svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents: 231
diff changeset
786 }
239
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
787
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
788 Statement *AsmBlockStatement::syntaxCopy()
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
789 {
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
790 Statements *a = new Statements();
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
791 a->setDim(statements->dim);
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
792 for (size_t i = 0; i < statements->dim; i++)
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
793 {
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
794 Statement *s = (Statement *)statements->data[i];
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
795 if (s)
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
796 s = s->syntaxCopy();
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
797 a->data[i] = s;
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
798 }
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
799 AsmBlockStatement *cs = new AsmBlockStatement(loc, a);
fa691b1c0498 [svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents: 237
diff changeset
800 return cs;
299
df8a7b8d5929 [svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents: 239
diff changeset
801 }
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
802
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
803 // necessary for in-asm branches
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
804 Statement *AsmBlockStatement::semantic(Scope *sc)
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
805 {
1141
f99a3b393c03 Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents: 1103
diff changeset
806 enclosingFinally = sc->enclosingFinally;
f99a3b393c03 Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents: 1103
diff changeset
807 enclosingScopeExit = sc->enclosingScopeExit;
302
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
808
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
809 return CompoundStatement::semantic(sc);
bef811104734 [svn r323] Branching out of inline asm works.
ChristianK
parents: 301
diff changeset
810 }
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
811
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
812 //////////////////////////////////////////////////////////////////////////////
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
813
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
814 void AsmStatement::toNakedIR(IRState *p)
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
815 {
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
816 Logger::println("AsmStatement::toNakedIR(): %s", loc.toChars());
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
817 LOG_SCOPE;
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
818
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
819 // is there code?
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
820 if (!asmcode)
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
821 return;
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
822 AsmCode * code = (AsmCode *) asmcode;
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
823
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
824 // build asm stmt
1102
ae950bd712d3 Use stringstream in asm generation instead of OutBuffer.
Frits van Bommel <fvbommel wxs.nl>
parents: 1101
diff changeset
825 p->nakedAsm << "\t" << code->insnTemplate << std::endl;
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
826 }
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
827
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
828 void AsmBlockStatement::toNakedIR(IRState *p)
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
829 {
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
830 Logger::println("AsmBlockStatement::toNakedIR(): %s", loc.toChars());
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
831 LOG_SCOPE;
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
832
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
833 // do asm statements
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
834 for (unsigned i=0; i<statements->dim; i++)
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
835 {
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
836 Statement* s = (Statement*)statements->data[i];
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
837 if (s) s->toNakedIR(p);
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
838 }
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 :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 794
diff changeset
839 }