Mercurial > projects > ldc
comparison gen/asmstmt.cpp @ 756:a58784e0f035
Merge wilsonk's x86-64 inline assembly.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 08 Nov 2008 22:29:19 +0100 |
parents | 26fce59fe80a |
children | f04dde6e882c |
comparison
equal
deleted
inserted
replaced
755:61c7a96f28c3 | 756:a58784e0f035 |
---|---|
55 | 55 |
56 struct AsmCode { | 56 struct AsmCode { |
57 char * insnTemplate; | 57 char * insnTemplate; |
58 unsigned insnTemplateLen; | 58 unsigned insnTemplateLen; |
59 Array args; // of AsmArg | 59 Array args; // of AsmArg |
60 unsigned moreRegs; | 60 std::vector<bool> regs; |
61 unsigned dollarLabel; | 61 unsigned dollarLabel; |
62 int clobbersMemory; | 62 int clobbersMemory; |
63 AsmCode() { | 63 AsmCode(int n_regs) { |
64 insnTemplate = NULL; | 64 insnTemplate = NULL; |
65 insnTemplateLen = 0; | 65 insnTemplateLen = 0; |
66 moreRegs = 0; | 66 regs.resize(n_regs, false); |
67 dollarLabel = 0; | 67 dollarLabel = 0; |
68 clobbersMemory = 0; | 68 clobbersMemory = 0; |
69 } | 69 } |
70 }; | 70 }; |
71 | 71 |
75 this->tokens = tokens; // Do I need to copy these? | 75 this->tokens = tokens; // Do I need to copy these? |
76 asmcode = 0; | 76 asmcode = 0; |
77 asmalign = 0; | 77 asmalign = 0; |
78 refparam = 0; | 78 refparam = 0; |
79 naked = 0; | 79 naked = 0; |
80 regs = 0; | |
81 | 80 |
82 isBranchToLabel = NULL; | 81 isBranchToLabel = NULL; |
83 } | 82 } |
84 | 83 |
85 Statement *AsmStatement::syntaxCopy() | 84 Statement *AsmStatement::syntaxCopy() |
87 // copy tokens? copy 'code'? | 86 // copy tokens? copy 'code'? |
88 AsmStatement * a_s = new AsmStatement(loc,tokens); | 87 AsmStatement * a_s = new AsmStatement(loc,tokens); |
89 a_s->asmcode = asmcode; | 88 a_s->asmcode = asmcode; |
90 a_s->refparam = refparam; | 89 a_s->refparam = refparam; |
91 a_s->naked = naked; | 90 a_s->naked = naked; |
92 a_s->regs = a_s->regs; | |
93 return a_s; | 91 return a_s; |
94 } | 92 } |
95 | 93 |
96 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 94 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
97 { | 95 { |
128 int AsmStatement::comeFrom() | 126 int AsmStatement::comeFrom() |
129 { | 127 { |
130 return FALSE; | 128 return FALSE; |
131 } | 129 } |
132 | 130 |
133 | 131 struct AsmParserCommon |
134 #include "d-asm-i386.h" | 132 { |
133 virtual void run(Scope* sc, AsmStatement* asmst) = 0; | |
134 virtual std::string getRegName(int i) = 0; | |
135 }; | |
136 AsmParserCommon* asmparser = NULL; | |
137 | |
138 #include "asm-x86-32.h" | |
139 #include "asm-x86-64.h" | |
135 | 140 |
136 bool d_have_inline_asm() { return true; } | 141 bool d_have_inline_asm() { return true; } |
137 | 142 |
138 Statement *AsmStatement::semantic(Scope *sc) | 143 Statement *AsmStatement::semantic(Scope *sc) |
139 { | 144 { |
140 bool err = false; | 145 bool err = false; |
141 if (global.params.cpu != ARCHx86) | 146 if ((global.params.cpu != ARCHx86) && (global.params.cpu != ARCHx86_64)) |
142 { | 147 { |
143 error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch); | 148 error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch); |
144 err = true; | 149 err = true; |
145 } | 150 } |
146 if (!global.params.useInlineAsm) | 151 if (!global.params.useInlineAsm) |
158 | 163 |
159 // empty statement -- still do the above things because they might be expected? | 164 // empty statement -- still do the above things because they might be expected? |
160 if (! tokens) | 165 if (! tokens) |
161 return this; | 166 return this; |
162 | 167 |
163 AsmProcessor ap(sc, this); | 168 if (!asmparser) |
164 ap.run(); | 169 if (global.params.cpu == ARCHx86) |
170 asmparser = new AsmParserx8632::AsmParser; | |
171 else if (global.params.cpu == ARCHx86_64) | |
172 asmparser = new AsmParserx8664::AsmParser; | |
173 | |
174 asmparser->run(sc, this); | |
175 | |
165 return this; | 176 return this; |
166 } | 177 } |
167 | 178 |
168 int AsmStatement::blockExit() | 179 int AsmStatement::blockExit() |
169 { | 180 { |
249 std::cout << "asm fixme Arg_FrameRelative" << std::endl; | 260 std::cout << "asm fixme Arg_FrameRelative" << std::endl; |
250 assert(0); | 261 assert(0); |
251 /* if (arg->expr->op == TOKvar) | 262 /* if (arg->expr->op == TOKvar) |
252 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; | 263 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; |
253 else | 264 else |
254 assert(0);*/ | 265 assert(0); |
255 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { | 266 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { |
256 // arg_val = irs->integerConstant(var_frame_offset); | 267 // arg_val = irs->integerConstant(var_frame_offset); |
257 cns = i_cns; | 268 cns = i_cns; |
258 } else { | 269 } else { |
259 this->error("%s", "argument not frame relative"); | 270 this->error("%s", "argument not frame relative"); |
260 return; | 271 return; |
261 } | 272 } |
262 if (arg->mode != Mode_Input) | 273 if (arg->mode != Mode_Input) |
263 clobbers_mem = true; | 274 clobbers_mem = true; |
264 break; | 275 break;*/ |
265 case Arg_LocalSize: | 276 case Arg_LocalSize: |
266 // FIXME | 277 // FIXME |
267 std::cout << "asm fixme Arg_LocalSize" << std::endl; | 278 std::cout << "asm fixme Arg_LocalSize" << std::endl; |
268 assert(0); | 279 assert(0); |
269 /* var_frame_offset = cfun->x_frame_offset; | 280 /* var_frame_offset = cfun->x_frame_offset; |
292 // those registers. This changes the stack from what a naked function | 303 // those registers. This changes the stack from what a naked function |
293 // expects. | 304 // expects. |
294 | 305 |
295 // FIXME | 306 // FIXME |
296 // if (! irs->func->naked) { | 307 // if (! irs->func->naked) { |
297 for (int i = 0; i < 32; i++) { | 308 assert(asmparser); |
298 if (regs & (1 << i)) { | 309 for (int i = 0; i < code->regs.size(); i++) { |
310 if (code->regs[i]) { | |
299 //clobbers.cons(NULL_TREE, regInfo[i].gccName); | 311 //clobbers.cons(NULL_TREE, regInfo[i].gccName); |
300 clobbers.push_back(regInfo[i].gccName); | 312 clobbers.push_back(asmparser->getRegName(i)); |
301 } | |
302 } | |
303 for (int i = 0; i < 32; i++) { | |
304 if (code->moreRegs & (1 << (i-32))) { | |
305 //clobbers.cons(NULL_TREE, regInfo[i].gccName); | |
306 clobbers.push_back(regInfo[i].gccName); | |
307 } | 313 } |
308 } | 314 } |
309 if (clobbers_mem) | 315 if (clobbers_mem) |
310 clobbers.push_back(memory_name); | 316 clobbers.push_back(memory_name); |
311 //clobbers.cons(NULL_TREE, memory_name); | 317 //clobbers.cons(NULL_TREE, memory_name); |