Mercurial > projects > ldc
comparison gen/asmstmt.cpp @ 1102:ae950bd712d3
Use stringstream in asm generation instead of OutBuffer.
Besides looking better, this should reduce allocations and copying.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Thu, 12 Mar 2009 14:08:57 +0100 |
parents | 8bf8b058944a |
children | b30fe7e1dbb9 |
comparison
equal
deleted
inserted
replaced
1101:8bf8b058944a | 1102:ae950bd712d3 |
---|---|
13 #include "dsymbol.h" | 13 #include "dsymbol.h" |
14 | 14 |
15 #include <cassert> | 15 #include <cassert> |
16 #include <deque> | 16 #include <deque> |
17 #include <cstring> | 17 #include <cstring> |
18 #include <string> | |
19 #include <sstream> | |
18 | 20 |
19 //#include "d-lang.h" | 21 //#include "d-lang.h" |
20 //#include "d-codegen.h" | 22 //#include "d-codegen.h" |
21 | 23 |
22 #include "gen/irstate.h" | 24 #include "gen/irstate.h" |
52 this->mode = mode; | 54 this->mode = mode; |
53 } | 55 } |
54 }; | 56 }; |
55 | 57 |
56 struct AsmCode { | 58 struct AsmCode { |
57 char * insnTemplate; | 59 std::string insnTemplate; |
58 unsigned insnTemplateLen; | |
59 std::vector<AsmArg> args; | 60 std::vector<AsmArg> args; |
60 std::vector<bool> regs; | 61 std::vector<bool> regs; |
61 unsigned dollarLabel; | 62 unsigned dollarLabel; |
62 int clobbersMemory; | 63 int clobbersMemory; |
63 AsmCode(int n_regs) { | 64 AsmCode(int n_regs) { |
64 insnTemplate = NULL; | |
65 insnTemplateLen = 0; | |
66 regs.resize(n_regs, false); | 65 regs.resize(n_regs, false); |
67 dollarLabel = 0; | 66 dollarLabel = 0; |
68 clobbersMemory = 0; | 67 clobbersMemory = 0; |
69 } | 68 } |
70 }; | 69 }; |
312 } | 311 } |
313 if (clobbers_mem) | 312 if (clobbers_mem) |
314 clobbers.push_back(memory_name); | 313 clobbers.push_back(memory_name); |
315 // } | 314 // } |
316 | 315 |
317 | |
318 // Remap argument numbers | 316 // Remap argument numbers |
319 for (unsigned i = 0; i < code->args.size(); i++) { | 317 for (unsigned i = 0; i < code->args.size(); i++) { |
320 if (arg_map[i] < 0) | 318 if (arg_map[i] < 0) |
321 arg_map[i] = -arg_map[i] - 1 + n_outputs; | 319 arg_map[i] = -arg_map[i] - 1 + n_outputs; |
322 } | 320 } |
323 | 321 |
324 bool pct = false; | 322 bool pct = false; |
325 char * p = code->insnTemplate; | 323 std::string::iterator |
326 char * q = p + code->insnTemplateLen; | 324 p = code->insnTemplate.begin(), |
325 q = code->insnTemplate.end(); | |
327 //printf("start: %.*s\n", code->insnTemplateLen, code->insnTemplate); | 326 //printf("start: %.*s\n", code->insnTemplateLen, code->insnTemplate); |
328 while (p < q) { | 327 while (p < q) { |
329 if (pct) { | 328 if (pct) { |
330 if (*p >= '0' && *p <= '9') { | 329 if (*p >= '0' && *p <= '9') { |
331 // %% doesn't check against nargs | 330 // %% doesn't check against nargs |
340 ++p; | 339 ++p; |
341 } | 340 } |
342 | 341 |
343 typedef std::vector<std::string>::iterator It; | 342 typedef std::vector<std::string>::iterator It; |
344 if (Logger::enabled()) { | 343 if (Logger::enabled()) { |
345 Logger::println("final asm: %.*s", code->insnTemplateLen, code->insnTemplate); | 344 Logger::cout() << "final asm: " << code->insnTemplate << '\n'; |
346 std::ostringstream ss; | 345 std::ostringstream ss; |
347 | 346 |
348 ss << "GCC-style output constraints: {"; | 347 ss << "GCC-style output constraints: {"; |
349 for (It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i) { | 348 for (It i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i) { |
350 ss << " " << *i; | 349 ss << " " << *i; |
366 ss << " " << *i; | 365 ss << " " << *i; |
367 } | 366 } |
368 ss << " }"; | 367 ss << " }"; |
369 Logger::println("%s", ss.str().c_str()); | 368 Logger::println("%s", ss.str().c_str()); |
370 } | 369 } |
371 | |
372 std::string insnt(code->insnTemplate, code->insnTemplateLen); | |
373 | 370 |
374 // rewrite GCC-style constraints to LLVM-style constraints | 371 // rewrite GCC-style constraints to LLVM-style constraints |
375 std::string llvmOutConstraints; | 372 std::string llvmOutConstraints; |
376 std::string llvmInConstraints; | 373 std::string llvmInConstraints; |
377 int n = 0; | 374 int n = 0; |
431 | 428 |
432 // excessive commas are removed later... | 429 // excessive commas are removed later... |
433 | 430 |
434 // push asm statement | 431 // push asm statement |
435 IRAsmStmt* asmStmt = new IRAsmStmt; | 432 IRAsmStmt* asmStmt = new IRAsmStmt; |
436 asmStmt->code = insnt; | 433 asmStmt->code = code->insnTemplate; |
437 asmStmt->out_c = llvmOutConstraints; | 434 asmStmt->out_c = llvmOutConstraints; |
438 asmStmt->in_c = llvmInConstraints; | 435 asmStmt->in_c = llvmInConstraints; |
439 asmStmt->out.insert(asmStmt->out.begin(), output_values.begin(), output_values.end()); | 436 asmStmt->out.insert(asmStmt->out.begin(), output_values.begin(), output_values.end()); |
440 asmStmt->in.insert(asmStmt->in.begin(), input_values.begin(), input_values.end()); | 437 asmStmt->in.insert(asmStmt->in.begin(), input_values.begin(), input_values.end()); |
441 asmStmt->isBranchToLabel = isBranchToLabel; | 438 asmStmt->isBranchToLabel = isBranchToLabel; |
823 if (!asmcode) | 820 if (!asmcode) |
824 return; | 821 return; |
825 AsmCode * code = (AsmCode *) asmcode; | 822 AsmCode * code = (AsmCode *) asmcode; |
826 | 823 |
827 // build asm stmt | 824 // build asm stmt |
828 std::ostringstream& asmstr = p->nakedAsm; | 825 p->nakedAsm << "\t" << code->insnTemplate << std::endl; |
829 asmstr << "\t"; | |
830 asmstr.write(code->insnTemplate, code->insnTemplateLen); | |
831 asmstr << std::endl; | |
832 } | 826 } |
833 | 827 |
834 void AsmBlockStatement::toNakedIR(IRState *p) | 828 void AsmBlockStatement::toNakedIR(IRState *p) |
835 { | 829 { |
836 Logger::println("AsmBlockStatement::toNakedIR(): %s", loc.toChars()); | 830 Logger::println("AsmBlockStatement::toNakedIR(): %s", loc.toChars()); |