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());