Mercurial > projects > ldc
annotate gen/asmstmt.cpp @ 979:523bf4f166bc
Fix some assembler issues:
The assembler was miscompiling "add" (specifically, the "add reg/mem, imm"
variations).
The change that caused this seems to have been made because without it, some
"add"s didn't compile at all.
This patch reverts the previous change, and makes sure assembler operands are
remapped correctly even though the input operands auto-generated due to
updating operations aren't explicitly used.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Wed, 18 Feb 2009 21:46:14 +0100 |
parents | 6a32d2e18175 |
children | ae710cba0884 |
rev | line source |
---|---|
304 | 1 // Taken from GDC source tree. Original by David Friedman. |
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> |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
17 #include <iostream> |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
18 #include <cstring> |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
19 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
20 //#include "d-lang.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
21 //#include "d-codegen.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
22 |
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
|
23 #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
|
24 #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
|
25 #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
|
26 #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
|
27 #include "gen/todebug.h" |
302 | 28 #include "gen/llvmhelpers.h" |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
29 #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
|
30 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
31 typedef enum { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
32 Arg_Integer, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
33 Arg_Pointer, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
34 Arg_Memory, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
35 Arg_FrameRelative, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
36 Arg_LocalSize, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
37 Arg_Dollar |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
38 } AsmArgType; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
39 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
40 typedef enum { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
41 Mode_Input, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
42 Mode_Output, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
43 Mode_Update |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
44 } AsmArgMode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
45 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
46 struct AsmArg { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
47 AsmArgType type; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
48 Expression * expr; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
49 AsmArgMode mode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
50 AsmArg(AsmArgType type, Expression * expr, AsmArgMode mode) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
51 this->type = type; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
52 this->expr = expr; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
53 this->mode = mode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
54 } |
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 struct AsmCode { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
58 char * insnTemplate; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
59 unsigned insnTemplateLen; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
60 Array args; // of AsmArg |
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) { |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
65 insnTemplate = NULL; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
66 insnTemplateLen = 0; |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
67 regs.resize(n_regs, false); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
68 dollarLabel = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
69 clobbersMemory = 0; |
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 }; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
72 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
73 AsmStatement::AsmStatement(Loc loc, Token *tokens) : |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
74 Statement(loc) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
75 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
76 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
|
77 asmcode = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
78 asmalign = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
79 refparam = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
80 naked = 0; |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
81 |
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
82 isBranchToLabel = NULL; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
83 } |
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 Statement *AsmStatement::syntaxCopy() |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
86 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
87 // copy tokens? copy 'code'? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
88 AsmStatement * a_s = new AsmStatement(loc,tokens); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
89 a_s->asmcode = asmcode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
90 a_s->refparam = refparam; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
91 a_s->naked = naked; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
92 return a_s; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
93 } |
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 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
96 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
97 bool sep = 0, nsep = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
98 buf->writestring("asm { "); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
99 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
100 for (Token * t = tokens; t; t = t->next) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
101 switch (t->value) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
102 case TOKlparen: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
103 case TOKrparen: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
104 case TOKlbracket: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
105 case TOKrbracket: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
106 case TOKcolon: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
107 case TOKsemicolon: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
108 case TOKcomma: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
109 case TOKstring: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
110 case TOKcharv: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
111 case TOKwcharv: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
112 case TOKdcharv: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
113 nsep = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
114 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
115 default: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
116 nsep = 1; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
117 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
118 if (sep + nsep == 2) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
119 buf->writeByte(' '); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
120 sep = nsep; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
121 buf->writestring(t->toChars()); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
122 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
123 buf->writestring("; }"); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
124 buf->writenl(); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
125 } |
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 int AsmStatement::comeFrom() |
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 return FALSE; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
130 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
131 |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
132 struct AsmParserCommon |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
133 { |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
134 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
|
135 virtual std::string getRegName(int i) = 0; |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
136 }; |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
137 AsmParserCommon* asmparser = NULL; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
138 |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
139 #include "asm-x86-32.h" |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
140 #include "asm-x86-64.h" |
219
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 bool d_have_inline_asm() { return true; } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
143 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
144 Statement *AsmStatement::semantic(Scope *sc) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
145 { |
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 bool err = false; |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
147 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
|
148 { |
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 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
|
150 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
|
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 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
|
153 { |
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 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
|
155 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
|
156 } |
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 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
|
158 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
|
159 |
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
|
160 //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
|
161 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
162 sc->func->inlineAsm = 1; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
163 sc->func->inlineStatus = ILSno; // %% not sure |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
164 // %% need to set DECL_UNINLINABLE too? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
165 sc->func->hasReturnExp = 1; // %% DMD does this, apparently... |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
166 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
167 // 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
|
168 if (! tokens) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
169 return this; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
170 |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
171 if (!asmparser) |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
172 if (global.params.cpu == ARCHx86) |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
173 asmparser = new AsmParserx8632::AsmParser; |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
174 else if (global.params.cpu == ARCHx86_64) |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
175 asmparser = new AsmParserx8664::AsmParser; |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
176 |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
177 asmparser->run(sc, this); |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
178 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
179 return this; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
180 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
181 |
336 | 182 int AsmStatement::blockExit() |
183 { | |
184 //printf("AsmStatement::blockExit(%p)\n", this); | |
185 return BEfallthru | BEreturn | BEgoto | BEhalt; | |
186 } | |
187 | |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
188 void |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
189 AsmStatement::toIR(IRState * irs) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
190 { |
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
|
191 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
|
192 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
|
193 |
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
|
194 // 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
|
195 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
|
196 |
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
|
197 // 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
|
198 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
|
199 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
|
200 |
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 // 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
|
202 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
|
203 DtoDwarfStopPoint(loc.linnum); |
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; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
216 std::deque<LLValue*> input_values; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
217 std::deque<std::string> input_constraints; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
218 std::deque<LLValue*> output_values; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
219 std::deque<std::string> output_constraints; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
220 std::deque<std::string> clobbers; |
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 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
223 #define HOST_WIDE_INT long |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
224 HOST_WIDE_INT var_frame_offset; // "frame_offset" is a macro |
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 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
230 assert(code->args.dim <= 10); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
231 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
232 for (unsigned i = 0; i < code->args.dim; i++) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
233 AsmArg * arg = (AsmArg *) code->args.data[i]; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
234 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
235 bool is_input = true; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
236 LLValue* arg_val = 0; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
237 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
|
238 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
239 switch (arg->type) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
240 case Arg_Integer: |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
241 arg_val = arg->expr->toElem(irs)->getRVal(); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
242 do_integer: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
243 cns = i_cns; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
244 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
245 case Arg_Pointer: |
234
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
233
diff
changeset
|
246 assert(arg->expr->op == TOKvar); |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
233
diff
changeset
|
247 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
|
248 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
|
249 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
250 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
251 case Arg_Memory: |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
252 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
|
253 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
254 switch (arg->mode) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
255 case Mode_Input: cns = m_cns; break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
256 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
|
257 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
|
258 default: assert(0); break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
259 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
260 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
261 case Arg_FrameRelative: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
262 // FIXME |
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
|
263 std::cout << "asm fixme Arg_FrameRelative" << std::endl; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
264 assert(0); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
265 /* if (arg->expr->op == TOKvar) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
266 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
267 else |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
268 assert(0); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
269 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
270 // arg_val = irs->integerConstant(var_frame_offset); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
271 cns = i_cns; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
272 } else { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
273 this->error("%s", "argument not frame relative"); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
274 return; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
275 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
276 if (arg->mode != Mode_Input) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
277 clobbers_mem = true; |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
278 break;*/ |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
279 case Arg_LocalSize: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
280 // FIXME |
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
|
281 std::cout << "asm fixme Arg_LocalSize" << std::endl; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
282 assert(0); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
283 /* var_frame_offset = cfun->x_frame_offset; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
284 if (var_frame_offset < 0) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
285 var_frame_offset = - var_frame_offset; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
286 arg_val = irs->integerConstant( var_frame_offset );*/ |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
287 goto do_integer; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
288 default: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
289 assert(0); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
290 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
291 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
292 if (is_input) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
293 arg_map[i] = --input_idx; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
294 //inputs.cons(tree_cons(NULL_TREE, cns, NULL_TREE), arg_val); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
295 input_values.push_back(arg_val); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
296 input_constraints.push_back(cns); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
297 } else { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
298 arg_map[i] = n_outputs++; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
299 //outputs.cons(tree_cons(NULL_TREE, cns, NULL_TREE), arg_val); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
300 output_values.push_back(arg_val); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
301 output_constraints.push_back(cns); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
302 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
303 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
304 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
305 // 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
|
306 // 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
|
307 // expects. |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
308 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
309 // FIXME |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
310 // if (! irs->func->naked) { |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
311 assert(asmparser); |
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
312 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
|
313 if (code->regs[i]) { |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
314 //clobbers.cons(NULL_TREE, regInfo[i].gccName); |
756
a58784e0f035
Merge wilsonk's x86-64 inline assembly.
Christian Kamm <kamm incasoftware de>
parents:
622
diff
changeset
|
315 clobbers.push_back(asmparser->getRegName(i)); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
316 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
317 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
318 if (clobbers_mem) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
319 clobbers.push_back(memory_name); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
320 //clobbers.cons(NULL_TREE, memory_name); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
321 // } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
322 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
323 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
324 // Remap argument numbers |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
325 for (unsigned i = 0; i < code->args.dim; i++) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
326 if (arg_map[i] < 0) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
327 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
|
328 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
329 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
330 bool pct = false; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
331 char * p = code->insnTemplate; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
332 char * q = p + code->insnTemplateLen; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
333 //printf("start: %.*s\n", code->insnTemplateLen, code->insnTemplate); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
334 while (p < q) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
335 if (pct) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
336 if (*p >= '0' && *p <= '9') { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
337 // %% doesn't check against nargs |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
338 *p = '0' + arg_map[*p - '0']; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
339 pct = false; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
340 } else if (*p == '$') { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
341 pct = false; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
342 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
343 //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
|
344 } else if (*p == '$') |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
345 pct = true; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
346 ++p; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
347 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
348 |
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
|
349 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
|
350 Logger::println("final asm: %.*s", code->insnTemplateLen, code->insnTemplate); |
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 std::ostringstream 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 |
fe2d9bb7078d
Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents:
959
diff
changeset
|
353 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
|
354 typedef std::deque<std::string>::iterator It; |
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 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
|
356 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
|
357 } |
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 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
|
359 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
|
360 |
fe2d9bb7078d
Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents:
959
diff
changeset
|
361 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
|
362 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
|
363 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
|
364 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
|
365 } |
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 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
|
367 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
|
368 |
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 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
|
370 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
|
371 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
|
372 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
|
373 } |
fe2d9bb7078d
Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents:
959
diff
changeset
|
374 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
|
375 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
|
376 } |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
377 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
378 std::string insnt(code->insnTemplate, code->insnTemplateLen); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
379 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
380 // 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
|
381 std::string llvmOutConstraints; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
382 std::string llvmInConstraints; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
383 int n = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
384 typedef std::deque<std::string>::iterator it; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
385 for(it i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i, ++n) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
386 // rewrite update constraint to in and out constraints |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
387 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
|
388 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
|
389 /* 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
|
390 * 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
|
391 */ |
985104c0f1db
Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents:
969
diff
changeset
|
392 |
985104c0f1db
Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents:
969
diff
changeset
|
393 // 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
|
394 *i = mw_cns; |
985104c0f1db
Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents:
969
diff
changeset
|
395 |
985104c0f1db
Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents:
969
diff
changeset
|
396 // 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
|
397 std::ostringstream ss; |
978
6a32d2e18175
Fix a latent bug in the asm code.
Frits van Bommel <fvbommel wxs.nl>
parents:
971
diff
changeset
|
398 ss << '*' << (n + asmblock->outputcount); |
979
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
399 // 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
|
400 input_constraints.push_back(ss.str()); |
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
401 input_values.push_back(output_values[n]); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
402 } |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
403 llvmOutConstraints += *i; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
404 llvmOutConstraints += ","; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
405 } |
971
985104c0f1db
Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents:
969
diff
changeset
|
406 asmblock->outputcount += n; |
985104c0f1db
Fix the problems exposed by the callingconv1.d test case.
Frits van Bommel <fvbommel wxs.nl>
parents:
969
diff
changeset
|
407 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
408 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
|
409 llvmInConstraints += *i; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
410 llvmInConstraints += ","; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
411 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
412 |
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
|
413 std::string clobstr; |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
414 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
|
415 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
|
416 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
|
417 } |
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
|
418 |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
419 // 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
|
420 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
421 // push asm statement |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
422 IRAsmStmt* asmStmt = new IRAsmStmt; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
423 asmStmt->code = insnt; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
424 asmStmt->out_c = llvmOutConstraints; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
425 asmStmt->in_c = llvmInConstraints; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
426 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
|
427 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
|
428 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
|
429 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
|
430 } |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
431 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
432 ////////////////////////////////////////////////////////////////////////////// |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
433 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
434 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
|
435 : CompoundStatement(loc, s) |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
436 { |
309 | 437 enclosinghandler = NULL; |
356
44daf304421c
[svn r377] The previous check was too strict, it completely disallowed gotos within finally blocks. This reenables them as long as they don't cross a finally boundary.
ChristianK
parents:
336
diff
changeset
|
438 tf = NULL; |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
439 |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
440 abiret = NULL; |
232
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 // rewrite argument indices to the block scope indices |
979
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
444 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
|
445 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
446 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
|
447 { |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
448 "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
|
449 "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
|
450 }; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
451 assert(nargs <= 10); |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
452 |
234
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
233
diff
changeset
|
453 static const std::string prefix("<<out"); |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
233
diff
changeset
|
454 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
|
455 std::string argnum; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
456 std::string needle; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
457 char buf[10]; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
458 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
|
459 needle = prefix + digits[i] + suffix; |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
460 size_t pos = insnt.find(needle); |
303 | 461 if(std::string::npos != pos) |
794
661384d6a936
Fix warnings on x86-64. By fvbommel.
Christian Kamm <kamm incasoftware de>
parents:
758
diff
changeset
|
462 sprintf(buf, "%" PRIuSIZE, idx++); |
302 | 463 while(std::string::npos != (pos = insnt.find(needle))) |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
464 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
|
465 } |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
466 } |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
467 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
468 // rewrite argument indices to the block scope indices |
979
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
469 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
|
470 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
471 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
|
472 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
473 "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
|
474 "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
|
475 }; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
476 assert(nargs <= 10); |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
477 |
234
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
233
diff
changeset
|
478 static const std::string prefix("<<in"); |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
233
diff
changeset
|
479 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
|
480 std::string argnum; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
481 std::string needle; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
482 char buf[10]; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
483 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
|
484 needle = prefix + digits[i] + suffix; |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
485 size_t pos = insnt.find(needle); |
303 | 486 if(std::string::npos != pos) |
794
661384d6a936
Fix warnings on x86-64. By fvbommel.
Christian Kamm <kamm incasoftware de>
parents:
758
diff
changeset
|
487 sprintf(buf, "%" PRIuSIZE, idx++); |
302 | 488 while(std::string::npos != (pos = insnt.find(needle))) |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
489 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
|
490 } |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
491 } |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
492 |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
493 LLValue* DtoAggrPairSwap(LLValue* aggr); |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
494 |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
495 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
|
496 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
497 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
|
498 LOG_SCOPE; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
499 Logger::println("BEGIN ASM"); |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
500 |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
501 // disable inlining by default |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
502 if (!p->func()->decl->allowInlining) |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
503 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
|
504 |
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
|
505 // 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
|
506 assert(!p->asmBlock); |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
507 IRAsmBlock* asmblock = new IRAsmBlock(this); |
239
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
508 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
|
509 p->asmBlock = asmblock; |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
510 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
511 // do asm statements |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
512 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
|
513 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
514 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
|
515 if (s) { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
516 s->toIR(p); |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
517 } |
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
|
518 } |
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
|
519 |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
520 // 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
|
521 // 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
|
522 // 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
|
523 // a post-asm switch |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
524 |
312
553f844ae5b9
[svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents:
309
diff
changeset
|
525 // 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
|
526 std::map<Identifier*, int> gotoToVal; |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
527 |
312
553f844ae5b9
[svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents:
309
diff
changeset
|
528 // location of the special value determining the goto label |
302 | 529 // will be set if post-asm dispatcher block is needed |
530 llvm::AllocaInst* jump_target; | |
301
f42a1090e895
[svn r322] More asm-to-outside jumping work. Unfinished.
ChristianK
parents:
300
diff
changeset
|
531 |
302 | 532 { |
305
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
304
diff
changeset
|
533 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
|
534 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
|
535 |
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
304
diff
changeset
|
536 // 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
|
537 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
|
538 std::ostringstream asmGotoEndLabel; |
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
304
diff
changeset
|
539 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
|
540 |
302 | 541 // initialize the setter statement we're going to build |
542 IRAsmStmt* outSetterStmt = new IRAsmStmt; | |
305
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
304
diff
changeset
|
543 std::string asmGotoEnd = "jmp "+asmGotoEndLabel.str()+" ; "; |
302 | 544 std::ostringstream code; |
545 code << asmGotoEnd; | |
546 | |
547 int n_goto = 1; | |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
548 |
302 | 549 size_t n = asmblock->s.size(); |
550 for(size_t i=0; i<n; ++i) | |
551 { | |
552 IRAsmStmt* a = asmblock->s[i]; | |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
553 |
302 | 554 // skip non-branch statements |
555 if(!a->isBranchToLabel) | |
556 continue; | |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
557 |
302 | 558 // if internal, no special handling is necessary, skip |
559 std::vector<Identifier*>::const_iterator it, end; | |
560 end = asmblock->internalLabels.end(); | |
561 bool skip = false; | |
562 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
|
563 if((*it)->equals(a->isBranchToLabel)) |
302 | 564 skip = true; |
565 if(skip) | |
566 continue; | |
567 | |
312
553f844ae5b9
[svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents:
309
diff
changeset
|
568 // 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
|
569 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
|
570 continue; |
553f844ae5b9
[svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents:
309
diff
changeset
|
571 |
302 | 572 // 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
|
573 gotoToVal[a->isBranchToLabel] = n_goto; |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
574 |
302 | 575 // 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
|
576 Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string); |
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
304
diff
changeset
|
577 code << fdmangle << '_' << a->isBranchToLabel->string << ": ; "; |
302 | 578 code << "movl $<<in" << n_goto << ">>, $<<out0>> ; "; |
579 //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
|
580 outSetterStmt->in.push_back(DtoConstUint(n_goto)); |
302 | 581 outSetterStmt->in_c += "i,"; |
582 code << asmGotoEnd; | |
583 | |
584 ++n_goto; | |
585 } | |
586 if(code.str() != asmGotoEnd) | |
587 { | |
588 // finalize code | |
589 outSetterStmt->code = code.str(); | |
305
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
304
diff
changeset
|
590 outSetterStmt->code += asmGotoEndLabel.str()+": ; "; |
302 | 591 |
592 // create storage for and initialize the temporary | |
479
672eb4893b55
Move AllocaInst creation into DtoAlloca helper. Will enable special zero-init of fp80 reals' padding.
Christian Kamm <kamm incasoftware de>
parents:
356
diff
changeset
|
593 jump_target = DtoAlloca(LLType::Int32Ty, "__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
|
594 gIR->ir->CreateStore(DtoConstUint(0), jump_target); |
302 | 595 // setup variable for output from asm |
596 outSetterStmt->out_c = "=*m,"; | |
597 outSetterStmt->out.push_back(jump_target); | |
598 | |
599 asmblock->s.push_back(outSetterStmt); | |
600 } | |
601 else | |
602 delete outSetterStmt; | |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
603 } |
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
604 |
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
605 |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
606 // 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
|
607 |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
608 FuncDeclaration* thisfunc = p->func()->decl; |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
609 bool useabiret = false; |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
610 p->asmBlock->asmBlock->abiret = NULL; |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
611 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
|
612 { |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
613 // 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
|
614 assert(gotoToVal.empty()); |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
615 emitABIReturnAsmStmt(asmblock, loc, thisfunc); |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
616 useabiret = true; |
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 |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
619 |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
620 // build asm block |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
621 std::vector<LLValue*> outargs; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
622 std::vector<LLValue*> inargs; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
623 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
|
624 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
|
625 std::string out_c; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
626 std::string in_c; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
627 std::string clobbers; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
628 std::string code; |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
629 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
|
630 |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
631 Logger::println("do outputs"); |
302 | 632 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
|
633 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
|
634 { |
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
|
635 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
|
636 assert(a); |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
637 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
|
638 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
|
639 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
640 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
|
641 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
|
642 } |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
643 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
|
644 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
645 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
|
646 } |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
647 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
|
648 asmIdx += onn; |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
649 } |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
650 |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
651 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
|
652 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
|
653 { |
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
|
654 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
|
655 assert(a); |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
656 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
|
657 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
|
658 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
659 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
|
660 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
|
661 } |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
662 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
|
663 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
664 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
|
665 } |
300
7b1040c76dd2
[svn r321] Fix bug in argument remapping functions.
ChristianK
parents:
299
diff
changeset
|
666 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
|
667 asmIdx += inn; |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
668 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
|
669 code += "\n\t"; |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
670 code += a->code; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
671 } |
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
|
672 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
|
673 |
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
|
674 // 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
|
675 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
|
676 |
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
|
677 // 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
|
678 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
|
679 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
|
680 { |
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
|
681 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
|
682 } |
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 // remove excessive comma |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
685 if (!out_c.empty()) |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
686 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
|
687 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
688 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
|
689 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
|
690 |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
691 // build return types |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
692 const LLType* retty; |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
693 if (asmblock->retn) |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
694 retty = asmblock->retty; |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
695 else |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
696 retty = llvm::Type::VoidTy; |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
697 |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
698 // build argument types |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
699 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
|
700 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
|
701 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
|
702 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
|
703 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
|
704 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
|
705 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
706 std::vector<LLValue*> args; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
707 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
|
708 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
|
709 |
fe2d9bb7078d
Add some extra debug output that's useful in diagnosing inline assembler bugs.
Frits van Bommel <fvbommel wxs.nl>
parents:
959
diff
changeset
|
710 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
|
711 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
|
712 Logger::indent(); |
979
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
713 for (std::vector<LLValue*>::iterator b = args.begin(), i = b, e = args.end(); i != e; ++i) { |
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
714 std::ostream& cout = Logger::cout(); |
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
715 cout << '$' << (i - b) << " ==> " << **i; |
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
716 if (llvm::isa<LLConstant>(*i)) |
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
717 cout << '\n'; |
523bf4f166bc
Fix some assembler issues:
Frits van Bommel <fvbommel wxs.nl>
parents:
978
diff
changeset
|
718 } |
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 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
|
720 } |
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 |
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 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
|
723 |
959
7e669954db7d
Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents:
954
diff
changeset
|
724 llvm::CallInst* call = p->ir->CreateCall(ia, args.begin(), args.end(), |
7e669954db7d
Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents:
954
diff
changeset
|
725 retty == LLType::VoidTy ? "" : "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
|
726 |
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
|
727 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
|
728 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
|
729 |
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
|
730 // capture abi return value |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
731 if (useabiret) |
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
732 { |
959
7e669954db7d
Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents:
954
diff
changeset
|
733 IRAsmBlock* block = p->asmBlock; |
7e669954db7d
Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents:
954
diff
changeset
|
734 if (block->retfixup) |
7e669954db7d
Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents:
954
diff
changeset
|
735 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
|
736 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
|
737 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
|
738 else |
959
7e669954db7d
Implement implicit return after inline asm on x86_64
Frits van Bommel <fvbommel wxs.nl>
parents:
954
diff
changeset
|
739 block->asmBlock->abiret = call; |
945
03d7c4aac654
SWITCHED TO LLVM 2.5 !
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
920
diff
changeset
|
740 } |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
741 |
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
|
742 p->asmBlock = NULL; |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
743 Logger::println("END ASM"); |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
744 |
302 | 745 // 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
|
746 if(!gotoToVal.empty()) |
302 | 747 { |
748 assert(jump_target); | |
749 | |
750 // make new blocks | |
751 llvm::BasicBlock* oldend = gIR->scopeend(); | |
752 llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterasmgotoforwarder", p->topfunc(), oldend); | |
753 | |
754 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
|
755 llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size()); |
302 | 756 |
757 // add all cases | |
312
553f844ae5b9
[svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents:
309
diff
changeset
|
758 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
|
759 for(it = gotoToVal.begin(); it != end; ++it) |
302 | 760 { |
761 llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb); | |
312
553f844ae5b9
[svn r333] Fix inline asm bug with multiple branches to the same label.
ChristianK
parents:
309
diff
changeset
|
762 sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->second), casebb); |
302 | 763 |
764 p->scope() = IRScope(casebb,bb); | |
356
44daf304421c
[svn r377] The previous check was too strict, it completely disallowed gotos within finally blocks. This reenables them as long as they don't cross a finally boundary.
ChristianK
parents:
336
diff
changeset
|
765 DtoGoto(&loc, it->first, enclosinghandler, tf); |
302 | 766 } |
767 | |
768 p->scope() = IRScope(bb,oldend); | |
769 } | |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
770 } |
232
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
771 |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
772 // 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
|
773 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
|
774 { |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
775 return NULL; |
092468448d25
[svn r248] Fixed: labels in inline asm block now work for the normal case.
lindquist
parents:
231
diff
changeset
|
776 } |
239
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
777 |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
778 Statement *AsmBlockStatement::syntaxCopy() |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
779 { |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
780 Statements *a = new Statements(); |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
781 a->setDim(statements->dim); |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
782 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
|
783 { |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
784 Statement *s = (Statement *)statements->data[i]; |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
785 if (s) |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
786 s = s->syntaxCopy(); |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
787 a->data[i] = s; |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
788 } |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
789 AsmBlockStatement *cs = new AsmBlockStatement(loc, a); |
fa691b1c0498
[svn r256] AsmBlockStatement was still being flattened in some cases.
lindquist
parents:
237
diff
changeset
|
790 return cs; |
299
df8a7b8d5929
[svn r320] Begun work on branches out of asm blocks. Unfinished.
ChristianK
parents:
239
diff
changeset
|
791 } |
302 | 792 |
793 // necessary for in-asm branches | |
794 Statement *AsmBlockStatement::semantic(Scope *sc) | |
795 { | |
309 | 796 enclosinghandler = sc->tfOfTry; |
356
44daf304421c
[svn r377] The previous check was too strict, it completely disallowed gotos within finally blocks. This reenables them as long as they don't cross a finally boundary.
ChristianK
parents:
336
diff
changeset
|
797 tf = sc->tf; |
302 | 798 |
799 return CompoundStatement::semantic(sc); | |
800 } | |
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
|
801 |
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
|
802 ////////////////////////////////////////////////////////////////////////////// |
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
|
803 |
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
|
804 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
|
805 { |
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
|
806 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
|
807 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
|
808 |
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
|
809 // 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
|
810 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
|
811 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
|
812 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
|
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 // build asm stmt |
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 std::ostringstream& asmstr = p->nakedAsm; |
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 asmstr << "\t"; |
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 asmstr.write(code->insnTemplate, code->insnTemplateLen); |
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 asmstr << std::endl; |
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 } |
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 |
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 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
|
822 { |
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 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
|
824 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
|
825 |
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 // 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
|
827 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
|
828 { |
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 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
|
830 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
|
831 } |
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 } |