comparison gen/asmstmt.cpp @ 300:7b1040c76dd2 trunk

[svn r321] Fix bug in argument remapping functions.
author ChristianK
date Tue, 24 Jun 2008 22:27:55 +0200
parents df8a7b8d5929
children f42a1090e895
comparison
equal deleted inserted replaced
299:df8a7b8d5929 300:7b1040c76dd2
461 std::string argnum; 461 std::string argnum;
462 std::string needle; 462 std::string needle;
463 char buf[10]; 463 char buf[10];
464 for (unsigned i = 0; i < nargs; i++) { 464 for (unsigned i = 0; i < nargs; i++) {
465 needle = prefix + digits[i] + suffix; 465 needle = prefix + digits[i] + suffix;
466 sprintf(buf, "%u", idx++); 466 size_t pos = insnt.find(needle);
467 insnt.replace(insnt.find(needle), needle.size(), buf); 467 if(pos != std::string::npos) {
468 sprintf(buf, "%u", idx++);
469 insnt.replace(pos, needle.size(), buf);
470 }
468 } 471 }
469 } 472 }
470 473
471 // rewrite argument indices to the block scope indices 474 // rewrite argument indices to the block scope indices
472 static void remap_inargs(std::string& insnt, size_t nargs, size_t& idx) 475 static void remap_inargs(std::string& insnt, size_t nargs, size_t& idx)
483 std::string argnum; 486 std::string argnum;
484 std::string needle; 487 std::string needle;
485 char buf[10]; 488 char buf[10];
486 for (unsigned i = 0; i < nargs; i++) { 489 for (unsigned i = 0; i < nargs; i++) {
487 needle = prefix + digits[i] + suffix; 490 needle = prefix + digits[i] + suffix;
488 sprintf(buf, "%u", idx++); 491 size_t pos = insnt.find(needle);
489 insnt.replace(insnt.find(needle), needle.size(), buf); 492 if(pos != std::string::npos) {
493 sprintf(buf, "%u", idx++);
494 insnt.replace(pos, needle.size(), buf);
495 }
490 } 496 }
491 } 497 }
492 498
493 void AsmBlockStatement::toIR(IRState* p) 499 void AsmBlockStatement::toIR(IRState* p)
494 { 500 {
513 519
514 // build forwarder for in-asm branches to external labels 520 // build forwarder for in-asm branches to external labels
515 // this additional asm code sets the __llvm_jump_target variable 521 // this additional asm code sets the __llvm_jump_target variable
516 // to a unique value that will identify the jump target in 522 // to a unique value that will identify the jump target in
517 // a post-asm switch 523 // a post-asm switch
518 //FIXME: Need to init __llvm_jump_target 524
525 // create storage for and initialize the temporary
526 llvm::AllocaInst* jump_target = new llvm::AllocaInst(llvm::IntegerType::get(32), "__llvm_jump_target", p->topallocapoint());
527 gIR->ir->CreateStore(llvm::ConstantInt::get(llvm::IntegerType::get(32), 0), jump_target);
528
519 //FIXME: Store the value -> label mapping somewhere, so it can be referenced later 529 //FIXME: Store the value -> label mapping somewhere, so it can be referenced later
520 std::string asmGotoEnd = "jmp __llvm_asm_end ; "; 530 std::string asmGotoEnd = "jmp __llvm_asm_end ; ";
521 std::string outGotoSetter = asmGotoEnd; 531 std::string outGotoSetter = asmGotoEnd;
522 532
523 size_t n = asmblock->s.size(); 533 size_t n = asmblock->s.size();
580 } 590 }
581 if (!a->out_c.empty()) 591 if (!a->out_c.empty())
582 { 592 {
583 out_c += a->out_c; 593 out_c += a->out_c;
584 } 594 }
585 remap_outargs(a->code, onn, asmIdx); 595 remap_outargs(a->code, onn+a->in.size(), asmIdx);
586 } 596 }
587 for (size_t i=0; i<n; ++i) 597 for (size_t i=0; i<n; ++i)
588 { 598 {
589 IRAsmStmt* a = asmblock->s[i]; 599 IRAsmStmt* a = asmblock->s[i];
590 assert(a); 600 assert(a);
596 } 606 }
597 if (!a->in_c.empty()) 607 if (!a->in_c.empty())
598 { 608 {
599 in_c += a->in_c; 609 in_c += a->in_c;
600 } 610 }
601 remap_inargs(a->code, inn, asmIdx); 611 remap_inargs(a->code, inn+a->out.size(), asmIdx);
602 if (!code.empty()) 612 if (!code.empty())
603 code += " ; "; 613 code += " ; ";
604 code += a->code; 614 code += a->code;
605 } 615 }
606 asmblock->s.clear(); 616 asmblock->s.clear();