Mercurial > projects > ldc
comparison gen/asmstmt.cpp @ 1101:8bf8b058944a
Clean up asm code a bit.
- Use vector instead of Array, reducing allocations.
- Use vectors instead of deques since we only push_back and index.
- Remove redundant typedefs of iterators.
- Comment out unused variable (used only in commented-out GDC code).
- A few whitespace changes.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Thu, 12 Mar 2009 14:08:57 +0100 |
parents | 11e28922ac76 |
children | ae950bd712d3 |
comparison
equal
deleted
inserted
replaced
1100:b3a0cf072ed0 | 1101:8bf8b058944a |
---|---|
41 Mode_Output, | 41 Mode_Output, |
42 Mode_Update | 42 Mode_Update |
43 } AsmArgMode; | 43 } AsmArgMode; |
44 | 44 |
45 struct AsmArg { | 45 struct AsmArg { |
46 Expression * expr; | |
46 AsmArgType type; | 47 AsmArgType type; |
47 Expression * expr; | |
48 AsmArgMode mode; | 48 AsmArgMode mode; |
49 AsmArg(AsmArgType type, Expression * expr, AsmArgMode mode) { | 49 AsmArg(AsmArgType type, Expression * expr, AsmArgMode mode) { |
50 this->type = type; | 50 this->type = type; |
51 this->expr = expr; | 51 this->expr = expr; |
52 this->mode = mode; | 52 this->mode = mode; |
54 }; | 54 }; |
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 std::vector<AsmArg> args; |
60 std::vector<bool> regs; | 60 std::vector<bool> regs; |
61 unsigned dollarLabel; | 61 unsigned dollarLabel; |
62 int clobbersMemory; | 62 int clobbersMemory; |
63 AsmCode(int n_regs) { | 63 AsmCode(int n_regs) { |
64 insnTemplate = NULL; | 64 insnTemplate = NULL; |
210 static std::string mw_cns = "=*m"; | 210 static std::string mw_cns = "=*m"; |
211 static std::string mrw_cns = "+*m"; | 211 static std::string mrw_cns = "+*m"; |
212 static std::string memory_name = "memory"; | 212 static std::string memory_name = "memory"; |
213 | 213 |
214 AsmCode * code = (AsmCode *) asmcode; | 214 AsmCode * code = (AsmCode *) asmcode; |
215 std::deque<LLValue*> input_values; | 215 std::vector<LLValue*> input_values; |
216 std::deque<std::string> input_constraints; | 216 std::vector<std::string> input_constraints; |
217 std::deque<LLValue*> output_values; | 217 std::vector<LLValue*> output_values; |
218 std::deque<std::string> output_constraints; | 218 std::vector<std::string> output_constraints; |
219 std::deque<std::string> clobbers; | 219 std::vector<std::string> clobbers; |
220 | 220 |
221 // FIXME | 221 // FIXME |
222 #define HOST_WIDE_INT long | 222 //#define HOST_WIDE_INT long |
223 HOST_WIDE_INT var_frame_offset; // "frame_offset" is a macro | 223 //HOST_WIDE_INT var_frame_offset; // "frame_offset" is a macro |
224 bool clobbers_mem = code->clobbersMemory; | 224 bool clobbers_mem = code->clobbersMemory; |
225 int input_idx = 0; | 225 int input_idx = 0; |
226 int n_outputs = 0; | 226 int n_outputs = 0; |
227 int arg_map[10]; | 227 int arg_map[10]; |
228 | 228 |
229 assert(code->args.dim <= 10); | 229 assert(code->args.size() <= 10); |
230 | 230 |
231 for (unsigned i = 0; i < code->args.dim; i++) { | 231 std::vector<AsmArg>::iterator arg = code->args.begin(); |
232 AsmArg * arg = (AsmArg *) code->args.data[i]; | 232 for (unsigned i = 0; i < code->args.size(); i++, ++arg) { |
233 | |
234 bool is_input = true; | 233 bool is_input = true; |
235 LLValue* arg_val = 0; | 234 LLValue* arg_val = 0; |
236 std::string cns; | 235 std::string cns; |
237 | 236 |
238 switch (arg->type) { | 237 switch (arg->type) { |
288 assert(0); | 287 assert(0); |
289 } | 288 } |
290 | 289 |
291 if (is_input) { | 290 if (is_input) { |
292 arg_map[i] = --input_idx; | 291 arg_map[i] = --input_idx; |
293 //inputs.cons(tree_cons(NULL_TREE, cns, NULL_TREE), arg_val); | |
294 input_values.push_back(arg_val); | 292 input_values.push_back(arg_val); |
295 input_constraints.push_back(cns); | 293 input_constraints.push_back(cns); |
296 } else { | 294 } else { |
297 arg_map[i] = n_outputs++; | 295 arg_map[i] = n_outputs++; |
298 //outputs.cons(tree_cons(NULL_TREE, cns, NULL_TREE), arg_val); | |
299 output_values.push_back(arg_val); | 296 output_values.push_back(arg_val); |
300 output_constraints.push_back(cns); | 297 output_constraints.push_back(cns); |
301 } | 298 } |
302 } | 299 } |
303 | 300 |
308 // FIXME | 305 // FIXME |
309 // if (! irs->func->naked) { | 306 // if (! irs->func->naked) { |
310 assert(asmparser); | 307 assert(asmparser); |
311 for (int i = 0; i < code->regs.size(); i++) { | 308 for (int i = 0; i < code->regs.size(); i++) { |
312 if (code->regs[i]) { | 309 if (code->regs[i]) { |
313 //clobbers.cons(NULL_TREE, regInfo[i].gccName); | |
314 clobbers.push_back(asmparser->getRegName(i)); | 310 clobbers.push_back(asmparser->getRegName(i)); |
315 } | 311 } |
316 } | 312 } |
317 if (clobbers_mem) | 313 if (clobbers_mem) |
318 clobbers.push_back(memory_name); | 314 clobbers.push_back(memory_name); |
319 //clobbers.cons(NULL_TREE, memory_name); | |
320 // } | 315 // } |
321 | 316 |
322 | 317 |
323 // Remap argument numbers | 318 // Remap argument numbers |
324 for (unsigned i = 0; i < code->args.dim; i++) { | 319 for (unsigned i = 0; i < code->args.size(); i++) { |
325 if (arg_map[i] < 0) | 320 if (arg_map[i] < 0) |
326 arg_map[i] = -arg_map[i] - 1 + n_outputs; | 321 arg_map[i] = -arg_map[i] - 1 + n_outputs; |
327 } | 322 } |
328 | 323 |
329 bool pct = false; | 324 bool pct = false; |
343 } else if (*p == '$') | 338 } else if (*p == '$') |
344 pct = true; | 339 pct = true; |
345 ++p; | 340 ++p; |
346 } | 341 } |
347 | 342 |
343 typedef std::vector<std::string>::iterator It; | |
348 if (Logger::enabled()) { | 344 if (Logger::enabled()) { |
349 Logger::println("final asm: %.*s", code->insnTemplateLen, code->insnTemplate); | 345 Logger::println("final asm: %.*s", code->insnTemplateLen, code->insnTemplate); |
350 std::ostringstream ss; | 346 std::ostringstream ss; |
351 | 347 |
352 ss << "GCC-style output constraints: {"; | 348 ss << "GCC-style output constraints: {"; |
353 typedef std::deque<std::string>::iterator It; | |
354 for (It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i) { | 349 for (It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i) { |
355 ss << " " << *i; | 350 ss << " " << *i; |
356 } | 351 } |
357 ss << " }"; | 352 ss << " }"; |
358 Logger::println("%s", ss.str().c_str()); | 353 Logger::println("%s", ss.str().c_str()); |
378 | 373 |
379 // rewrite GCC-style constraints to LLVM-style constraints | 374 // rewrite GCC-style constraints to LLVM-style constraints |
380 std::string llvmOutConstraints; | 375 std::string llvmOutConstraints; |
381 std::string llvmInConstraints; | 376 std::string llvmInConstraints; |
382 int n = 0; | 377 int n = 0; |
383 typedef std::deque<std::string>::iterator it; | 378 for(It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i, ++n) { |
384 for(it i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i, ++n) { | |
385 // rewrite update constraint to in and out constraints | 379 // rewrite update constraint to in and out constraints |
386 if((*i)[0] == '+') { | 380 if((*i)[0] == '+') { |
387 assert(*i == mrw_cns && "What else are we updating except memory?"); | 381 assert(*i == mrw_cns && "What else are we updating except memory?"); |
388 /* LLVM doesn't support updating operands, so split into an input | 382 /* LLVM doesn't support updating operands, so split into an input |
389 * and an output operand. | 383 * and an output operand. |
402 llvmOutConstraints += *i; | 396 llvmOutConstraints += *i; |
403 llvmOutConstraints += ","; | 397 llvmOutConstraints += ","; |
404 } | 398 } |
405 asmblock->outputcount += n; | 399 asmblock->outputcount += n; |
406 | 400 |
407 for(it i = input_constraints.begin(), e = input_constraints.end(); i != e; ++i) { | 401 for(It i = input_constraints.begin(), e = input_constraints.end(); i != e; ++i) { |
408 llvmInConstraints += *i; | 402 llvmInConstraints += *i; |
409 llvmInConstraints += ","; | 403 llvmInConstraints += ","; |
410 } | 404 } |
411 | 405 |
412 std::string clobstr; | 406 std::string clobstr; |
413 for(it i = clobbers.begin(), e = clobbers.end(); i != e; ++i) { | 407 for(It i = clobbers.begin(), e = clobbers.end(); i != e; ++i) { |
414 clobstr = "~{" + *i + "},"; | 408 clobstr = "~{" + *i + "},"; |
415 asmblock->clobs.insert(clobstr); | 409 asmblock->clobs.insert(clobstr); |
416 } | 410 } |
417 | 411 |
418 if (Logger::enabled()) { | 412 if (Logger::enabled()) { |
419 typedef std::deque<LLValue*>::iterator It; | 413 typedef std::vector<LLValue*>::iterator It; |
420 { | 414 { |
421 Logger::println("Output values:"); | 415 Logger::println("Output values:"); |
422 LOG_SCOPE | 416 LOG_SCOPE |
423 size_t i = 0; | 417 size_t i = 0; |
424 for (It I = output_values.begin(), E = output_values.end(); I != E; ++I) { | 418 for (It I = output_values.begin(), E = output_values.end(); I != E; ++I) { |