Mercurial > projects > ldc
annotate gen/asmstmt.cpp @ 231:61aa721a6b7f trunk
[svn r247] fixed accessing global symbols from inline asm.
author | lindquist |
---|---|
date | Sun, 08 Jun 2008 01:07:58 +0200 |
parents | cac3d27ae481 |
children | 092468448d25 |
rev | line source |
---|---|
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
1 // Taken from GDC source tree, licence unclear? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
2 // |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
3 // Taken from an earlier version of DMD -- why is it missing from 0.79? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
4 |
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
|
5 #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
|
6 #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
|
7 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
8 //#include "d-gcc-includes.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
9 //#include "total.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
10 #include "dmd/statement.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
11 #include "dmd/scope.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
12 #include "dmd/declaration.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
13 #include "dmd/dsymbol.h" |
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> |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
18 #include <sstream> |
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" |
ccc2e6898a78
[svn r236] added initial codegen of inline asm, pretty buggy and incomplete still. see the tangotests/asm1.d test for a sample of what does
lindquist
parents:
219
diff
changeset
|
27 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
28 typedef enum { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
29 Arg_Integer, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
30 Arg_Pointer, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
31 Arg_Memory, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
32 Arg_FrameRelative, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
33 Arg_LocalSize, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
34 Arg_Dollar |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
35 } AsmArgType; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
36 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
37 typedef enum { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
38 Mode_Input, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
39 Mode_Output, |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
40 Mode_Update |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
41 } AsmArgMode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
42 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
43 struct AsmArg { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
44 AsmArgType type; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
45 Expression * expr; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
46 AsmArgMode mode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
47 AsmArg(AsmArgType type, Expression * expr, AsmArgMode mode) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
48 this->type = type; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
49 this->expr = expr; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
50 this->mode = mode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
51 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
52 }; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
53 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
54 struct AsmCode { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
55 char * insnTemplate; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
56 unsigned insnTemplateLen; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
57 Array args; // of AsmArg |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
58 unsigned moreRegs; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
59 unsigned dollarLabel; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
60 int clobbersMemory; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
61 AsmCode() { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
62 insnTemplate = NULL; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
63 insnTemplateLen = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
64 moreRegs = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
65 dollarLabel = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
66 clobbersMemory = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
67 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
68 }; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
69 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
70 llvm::InlineAsm* |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
71 d_build_asm_stmt(std::string const& code, |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
72 std::deque<LLValue*> const& output_values, |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
73 std::deque<LLValue*> const& input_values, |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
74 std::string const& constraints) |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
75 { |
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
|
76 std::vector<const LLType*> params; |
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
|
77 |
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
|
78 // outputs |
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
|
79 const LLType* ret = LLType::VoidTy; |
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
|
80 if (!output_values.empty()) |
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
|
81 { |
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
|
82 assert(output_values.size() == 1); |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
83 const LLType* llty = output_values[0]->getType(); |
225
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
224
diff
changeset
|
84 std::cout << "out: " << *llty << '\n'; |
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
|
85 params.push_back(llty); |
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
|
86 } |
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
|
87 |
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
|
88 // inputs |
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
|
89 if (!input_values.empty()) |
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
|
90 { |
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
|
91 assert(input_values.size() == 1); |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
92 const LLType* llty = input_values[0]->getType(); |
225
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
224
diff
changeset
|
93 std::cout << "in: " << *llty << '\n'; |
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
|
94 params.push_back(llty); |
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
|
95 } |
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
|
96 |
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
|
97 llvm::FunctionType* asmfnty = llvm::FunctionType::get(ret, params, false); |
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
|
98 |
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
|
99 std::cout << "function type: " << std::endl; |
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
|
100 std::cout << *asmfnty << std::endl; |
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
|
101 |
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
|
102 return llvm::InlineAsm::get(asmfnty, code, constraints, true); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
103 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
104 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
105 AsmStatement::AsmStatement(Loc loc, Token *tokens) : |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
106 Statement(loc) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
107 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
108 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
|
109 asmcode = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
110 asmalign = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
111 refparam = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
112 naked = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
113 regs = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
114 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
115 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
116 Statement *AsmStatement::syntaxCopy() |
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 // copy tokens? copy 'code'? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
119 AsmStatement * a_s = new AsmStatement(loc,tokens); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
120 a_s->asmcode = asmcode; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
121 a_s->refparam = refparam; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
122 a_s->naked = naked; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
123 a_s->regs = a_s->regs; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
124 return a_s; |
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 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
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 bool sep = 0, nsep = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
130 buf->writestring("asm { "); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
131 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
132 for (Token * t = tokens; t; t = t->next) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
133 switch (t->value) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
134 case TOKlparen: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
135 case TOKrparen: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
136 case TOKlbracket: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
137 case TOKrbracket: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
138 case TOKcolon: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
139 case TOKsemicolon: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
140 case TOKcomma: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
141 case TOKstring: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
142 case TOKcharv: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
143 case TOKwcharv: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
144 case TOKdcharv: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
145 nsep = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
146 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
147 default: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
148 nsep = 1; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
149 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
150 if (sep + nsep == 2) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
151 buf->writeByte(' '); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
152 sep = nsep; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
153 buf->writestring(t->toChars()); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
154 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
155 buf->writestring("; }"); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
156 buf->writenl(); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
157 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
158 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
159 int AsmStatement::comeFrom() |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
160 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
161 return FALSE; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
162 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
163 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
164 /* GCC does not support jumps from asm statements. When optimization |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
165 is turned on, labels referenced only from asm statements will not |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
166 be output at the correct location. There are ways around this: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
167 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
168 1) Reference the label with a reachable goto statement |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
169 2) Have reachable computed goto in the function |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
170 3) Hack cfgbuild.c to act as though there is a computed goto. |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
171 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
172 These are all pretty bad, but if would be nice to be able to tell |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
173 GCC not to optimize in this case (even on per label/block basis). |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
174 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
175 The current solution is output our own private labels (as asm |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
176 statements) along with the "real" label. If the label happens to |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
177 be referred to by a goto statement, the "real" label will also be |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
178 output in the correct location. |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
179 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
180 Also had to add 'asmLabelNum' to LabelDsymbol to indicate it needs |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
181 special processing. |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
182 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
183 (junk) d-lang.cc:916:case LABEL_DECL: // C doesn't do this. D needs this for referencing labels in inline assembler since there may be not goto referencing it. |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
184 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
185 */ |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
186 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
187 static unsigned d_priv_asm_label_serial = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
188 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
189 // may need to make this target-specific |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
190 static void d_format_priv_asm_label(char * buf, unsigned n) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
191 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
192 //ASM_GENERATE_INTERNAL_LABEL(buf, "LDASM", n);//inserts a '*' for use with assemble_name |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
193 sprintf(buf, ".LDASM%u", n); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
194 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
195 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
196 void |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
197 d_expand_priv_asm_label(IRState * irs, unsigned n) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
198 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
199 /* char buf[64]; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
200 d_format_priv_asm_label(buf, n); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
201 strcat(buf, ":"); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
202 tree insnt = build_string(strlen(buf), buf); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
203 #if D_GCC_VER < 40 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
204 expand_asm(insnt, 1); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
205 #else |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
206 tree t = d_build_asm_stmt(insnt, NULL_TREE, NULL_TREE, NULL_TREE); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
207 ASM_VOLATILE_P( t ) = 1; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
208 ASM_INPUT_P( t) = 1; // what is this doing? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
209 irs->addExp(t); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
210 #endif*/ |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
211 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
212 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
213 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
214 // StringExp::toIR usually adds a NULL. We don't want that... |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
215 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
216 /*static tree |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
217 naturalString(Expression * e) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
218 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
219 // don't fail, just an error? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
220 assert(e->op == TOKstring); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
221 StringExp * s = (StringExp *) e; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
222 assert(s->sz == 1); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
223 return build_string(s->len, (char *) s->string); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
224 }*/ |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
225 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
226 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
227 #include "d-asm-i386.h" |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
228 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
229 bool d_have_inline_asm() { return true; } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
230 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
231 Statement *AsmStatement::semantic(Scope *sc) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
232 { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
233 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
234 sc->func->inlineAsm = 1; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
235 sc->func->inlineStatus = ILSno; // %% not sure |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
236 // %% need to set DECL_UNINLINABLE too? |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
237 sc->func->hasReturnExp = 1; // %% DMD does this, apparently... |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
238 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
239 // 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
|
240 if (! tokens) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
241 return this; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
242 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
243 AsmProcessor ap(sc, this); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
244 ap.run(); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
245 return this; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
246 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
247 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
248 void |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
249 AsmStatement::toIR(IRState * irs) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
250 { |
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
|
251 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
|
252 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
|
253 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
254 // FIXME |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
255 // gen.doLineNote( loc ); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
256 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
257 if (! asmcode) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
258 return; |
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 static std::string i_cns = "i"; |
231
61aa721a6b7f
[svn r247] fixed accessing global symbols from inline asm.
lindquist
parents:
229
diff
changeset
|
261 static std::string p_cns = "i"; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
262 static std::string l_cns = "X"; |
222
251548c1035d
[svn r238] use *m for memory input constraints and pass in their address
ChristianK
parents:
221
diff
changeset
|
263 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
|
264 static std::string mw_cns = "=*m"; |
223
5ffca623b5df
[svn r239] also use indirect modifier for update constraints
ChristianK
parents:
222
diff
changeset
|
265 static std::string mrw_cns = "+*m"; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
266 static std::string memory_name = "memory"; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
267 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
268 AsmCode * code = (AsmCode *) asmcode; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
269 std::deque<LLValue*> input_values; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
270 std::deque<std::string> input_constraints; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
271 std::deque<LLValue*> output_values; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
272 std::deque<std::string> output_constraints; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
273 std::deque<std::string> clobbers; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
274 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
275 // FIXME |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
276 #define HOST_WIDE_INT long |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
277 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
|
278 bool clobbers_mem = code->clobbersMemory; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
279 int input_idx = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
280 int n_outputs = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
281 int arg_map[10]; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
282 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
283 assert(code->args.dim <= 10); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
284 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
285 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
|
286 AsmArg * arg = (AsmArg *) code->args.data[i]; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
287 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
288 bool is_input = true; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
289 LLValue* arg_val = 0; |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
290 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
|
291 |
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
|
292 std::cout << std::endl; |
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
|
293 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
294 switch (arg->type) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
295 case Arg_Integer: |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
296 arg_val = arg->expr->toElem(irs)->getRVal(); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
297 do_integer: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
298 cns = i_cns; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
299 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
300 case Arg_Pointer: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
301 // 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
|
302 std::cout << "asm fixme Arg_Pointer" << std::endl; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
303 if (arg->expr->op == TOKdsymbol) |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
304 { |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
305 DsymbolExp* dse = (DsymbolExp*)arg->expr; |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
306 LabelDsymbol* lbl = dse->s->isLabel(); |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
307 assert(lbl); |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
308 arg_val = lbl->statement->llvmBB; |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
309 if (!arg_val) |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
310 { |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
311 arg_val = lbl->statement->llvmBB = llvm::BasicBlock::Create("label", irs->topfunc()); |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
312 } |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
313 cns = l_cns; |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
314 } |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
315 else |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
316 { |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
317 arg_val = arg->expr->toElem(irs)->getRVal(); |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
318 cns = p_cns; |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
319 } |
226
4145266ff4bd
[svn r242] fixed (I think) arg_pointer inline asm args
lindquist
parents:
225
diff
changeset
|
320 /*if (arg->expr->op == TOKvar) |
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
|
321 arg_val = arg->expr->toElem(irs); |
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
|
322 else if (arg->expr->op == TOKdsymbol) |
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
|
323 arg_val = arg->expr->toElem(irs); |
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
|
324 else |
226
4145266ff4bd
[svn r242] fixed (I think) arg_pointer inline asm args
lindquist
parents:
225
diff
changeset
|
325 assert(0);*/ |
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
|
326 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
327 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
328 case Arg_Memory: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
329 // 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
|
330 std::cout << "asm fixme Arg_Memory" << std::endl; |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
331 arg_val = arg->expr->toElem(irs)->getRVal(); |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
332 // if (arg->expr->op == TOKvar) |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
333 // arg_val = arg->expr->toElem(irs); |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
334 // else |
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
335 // arg_val = arg->expr->toElem(irs); |
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
|
336 |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
337 switch (arg->mode) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
338 case Mode_Input: cns = m_cns; break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
339 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
|
340 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
|
341 default: assert(0); break; |
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 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
344 case Arg_FrameRelative: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
345 // 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
|
346 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
|
347 assert(0); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
348 /* if (arg->expr->op == TOKvar) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
349 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
350 else |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
351 assert(0);*/ |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
352 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
353 // arg_val = irs->integerConstant(var_frame_offset); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
354 cns = i_cns; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
355 } else { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
356 this->error("%s", "argument not frame relative"); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
357 return; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
358 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
359 if (arg->mode != Mode_Input) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
360 clobbers_mem = true; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
361 break; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
362 case Arg_LocalSize: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
363 // 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
|
364 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
|
365 assert(0); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
366 /* var_frame_offset = cfun->x_frame_offset; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
367 if (var_frame_offset < 0) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
368 var_frame_offset = - var_frame_offset; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
369 arg_val = irs->integerConstant( var_frame_offset );*/ |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
370 goto do_integer; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
371 default: |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
372 assert(0); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
373 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
374 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
375 if (is_input) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
376 arg_map[i] = --input_idx; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
377 //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
|
378 input_values.push_back(arg_val); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
379 input_constraints.push_back(cns); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
380 } else { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
381 arg_map[i] = n_outputs++; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
382 //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
|
383 output_values.push_back(arg_val); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
384 output_constraints.push_back(cns); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
385 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
386 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
387 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
388 // 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
|
389 // 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
|
390 // expects. |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
391 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
392 // FIXME |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
393 // if (! irs->func->naked) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
394 for (int i = 0; i < 32; i++) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
395 if (regs & (1 << i)) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
396 //clobbers.cons(NULL_TREE, regInfo[i].gccName); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
397 clobbers.push_back(regInfo[i].gccName); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
398 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
399 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
400 for (int i = 0; i < 32; i++) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
401 if (code->moreRegs & (1 << (i-32))) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
402 //clobbers.cons(NULL_TREE, regInfo[i].gccName); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
403 clobbers.push_back(regInfo[i].gccName); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
404 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
405 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
406 if (clobbers_mem) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
407 clobbers.push_back(memory_name); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
408 //clobbers.cons(NULL_TREE, memory_name); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
409 // } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
410 |
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 // Remap argument numbers |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
413 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
|
414 if (arg_map[i] < 0) |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
415 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
|
416 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
417 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
418 bool pct = false; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
419 char * p = code->insnTemplate; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
420 char * q = p + code->insnTemplateLen; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
421 //printf("start: %.*s\n", code->insnTemplateLen, code->insnTemplate); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
422 while (p < q) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
423 if (pct) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
424 if (*p >= '0' && *p <= '9') { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
425 // %% doesn't check against nargs |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
426 *p = '0' + arg_map[*p - '0']; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
427 pct = false; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
428 } else if (*p == '$') { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
429 pct = false; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
430 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
431 //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
|
432 } else if (*p == '$') |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
433 pct = true; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
434 ++p; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
435 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
436 |
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
|
437 printf("final: %.*s\n", code->insnTemplateLen, code->insnTemplate); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
438 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
439 std::string insnt(code->insnTemplate, code->insnTemplateLen); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
440 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
441 // rewrite GCC-style constraints to LLVM-style constraints |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
442 std::string llvmConstraints; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
443 int n = 0; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
444 typedef std::deque<std::string>::iterator it; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
445 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
|
446 // rewrite update constraint to in and out constraints |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
447 if((*i)[0] == '+') { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
448 (*i)[0] = '='; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
449 std::string input_constraint; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
450 std::stringstream ss; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
451 ss << n; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
452 ss >> input_constraint; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
453 //FIXME: I think multiple inout constraints will mess up the order! |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
454 input_constraints.push_front(input_constraint); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
455 input_values.push_front(output_values[n]); |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
456 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
457 llvmConstraints += *i; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
458 llvmConstraints += ","; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
459 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
460 for(it i = input_constraints.begin(), e = input_constraints.end(); i != e; ++i) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
461 llvmConstraints += *i; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
462 llvmConstraints += ","; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
463 } |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
464 for(it i = clobbers.begin(), e = clobbers.end(); i != e; ++i) { |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
465 llvmConstraints += "~{" + *i + "},"; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
466 } |
224
116cc012409b
[svn r240] do not crash on zero length constraints string
ChristianK
parents:
223
diff
changeset
|
467 if(llvmConstraints.size() > 0) |
116cc012409b
[svn r240] do not crash on zero length constraints string
ChristianK
parents:
223
diff
changeset
|
468 llvmConstraints.resize(llvmConstraints.size()-1); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
469 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
470 std::cout << "Inline Asm code: " << std::endl; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
471 std::cout << insnt << std::endl; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
472 std::cout << "LLVM constraints: " << llvmConstraints << std::endl; |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
473 |
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
474 llvm::InlineAsm* t = d_build_asm_stmt(insnt, output_values, input_values, llvmConstraints); |
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
|
475 |
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
|
476 std::cout << "llvm::InlineAsm: " << std::endl; |
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
|
477 std::cout << *t << std::endl; |
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
|
478 |
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
|
479 LLSmallVector<LLValue*, 2> callargs; |
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
|
480 |
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
|
481 size_t cn = output_values.size(); |
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
|
482 for (size_t i=0; i<cn; ++i) |
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
|
483 { |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
484 callargs.push_back(output_values[i]); |
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
|
485 } |
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
|
486 |
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
|
487 cn = input_values.size(); |
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
|
488 for (size_t i=0; i<cn; ++i) |
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
|
489 { |
229
cac3d27ae481
[svn r245] initial support for labels in inline asm, broken :/
lindquist
parents:
227
diff
changeset
|
490 callargs.push_back(input_values[i]); |
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
|
491 } |
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
|
492 |
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
|
493 llvm::CallInst* call = irs->ir->CreateCall(t, callargs.begin(), callargs.end(), ""); |
219
761c8352f494
[svn r235] rough port of GDC's inline assembler code, unfinished
ChristianK
parents:
diff
changeset
|
494 } |