comparison gen/asmstmt.cpp @ 299:df8a7b8d5929 trunk

[svn r320] Begun work on branches out of asm blocks. Unfinished.
author ChristianK
date Tue, 24 Jun 2008 21:38:23 +0200
parents fa691b1c0498
children 7b1040c76dd2
comparison
equal deleted inserted replaced
298:3b8ada4c9f8b 299:df8a7b8d5929
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; 80 regs = 0;
81
82 isBranchToLabel = NULL;
81 } 83 }
82 84
83 Statement *AsmStatement::syntaxCopy() 85 Statement *AsmStatement::syntaxCopy()
84 { 86 {
85 // copy tokens? copy 'code'? 87 // copy tokens? copy 'code'?
431 asmStmt->code = insnt; 433 asmStmt->code = insnt;
432 asmStmt->out_c = llvmOutConstraints; 434 asmStmt->out_c = llvmOutConstraints;
433 asmStmt->in_c = llvmInConstraints; 435 asmStmt->in_c = llvmInConstraints;
434 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());
435 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());
438 asmStmt->isBranchToLabel = isBranchToLabel;
436 asmblock->s.push_back(asmStmt); 439 asmblock->s.push_back(asmStmt);
437 } 440 }
438 441
439 ////////////////////////////////////////////////////////////////////////////// 442 //////////////////////////////////////////////////////////////////////////////
440 443
505 Statement* s = (Statement*)statements->data[i]; 508 Statement* s = (Statement*)statements->data[i];
506 if (s) { 509 if (s) {
507 s->toIR(p); 510 s->toIR(p);
508 } 511 }
509 } 512 }
513
514 // build forwarder for in-asm branches to external labels
515 // this additional asm code sets the __llvm_jump_target variable
516 // to a unique value that will identify the jump target in
517 // a post-asm switch
518 //FIXME: Need to init __llvm_jump_target
519 //FIXME: Store the value -> label mapping somewhere, so it can be referenced later
520 std::string asmGotoEnd = "jmp __llvm_asm_end ; ";
521 std::string outGotoSetter = asmGotoEnd;
522
523 size_t n = asmblock->s.size();
524 for(size_t i=0; i<n; ++i)
525 {
526 IRAsmStmt* a = asmblock->s[i];
527
528 // skip non-branch statements
529 if(!a->isBranchToLabel)
530 continue;
531
532 // if internal, no special handling is necessary, skip
533 std::vector<Identifier*>::const_iterator it, end;
534 end = asmblock->internalLabels.end();
535 bool skip = false;
536 for(it = asmblock->internalLabels.begin(); it != end; ++it)
537 if((*it)->equals(a->isBranchToLabel))
538 skip = true;
539 if(skip)
540 continue;
541
542 // provide an in-asm target for the branch and set value
543 Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string);
544 outGotoSetter += a->isBranchToLabel->string;
545 outGotoSetter += ": ; ";
546 outGotoSetter += "nop ; "; //FIXME: Change this to set __llvm_jump_target to a unique value
547 outGotoSetter += asmGotoEnd;
548 }
549 if(outGotoSetter != asmGotoEnd)
550 {
551 outGotoSetter += "__llvm_asm_end: ; ";
552 IRAsmStmt* outSetterStmt = new IRAsmStmt;
553 outSetterStmt->code = outGotoSetter;
554 //FIXME: set other stuff
555 asmblock->s.push_back(outSetterStmt);
556 }
557
510 558
511 // build asm block 559 // build asm block
512 std::vector<LLValue*> outargs; 560 std::vector<LLValue*> outargs;
513 std::vector<LLValue*> inargs; 561 std::vector<LLValue*> inargs;
514 std::vector<const LLType*> outtypes; 562 std::vector<const LLType*> outtypes;
517 std::string in_c; 565 std::string in_c;
518 std::string clobbers; 566 std::string clobbers;
519 std::string code; 567 std::string code;
520 size_t asmIdx = 0; 568 size_t asmIdx = 0;
521 569
522 size_t n = asmblock->s.size(); 570 n = asmblock->s.size();
523 for (size_t i=0; i<n; ++i) 571 for (size_t i=0; i<n; ++i)
524 { 572 {
525 IRAsmStmt* a = asmblock->s[i]; 573 IRAsmStmt* a = asmblock->s[i];
526 assert(a); 574 assert(a);
527 size_t onn = a->out.size(); 575 size_t onn = a->out.size();
586 args.insert(args.end(), inargs.begin(), inargs.end()); 634 args.insert(args.end(), inargs.begin(), inargs.end());
587 llvm::CallInst* call = p->ir->CreateCall(ia, args.begin(), args.end(), ""); 635 llvm::CallInst* call = p->ir->CreateCall(ia, args.begin(), args.end(), "");
588 636
589 p->asmBlock = NULL; 637 p->asmBlock = NULL;
590 Logger::println("END ASM"); 638 Logger::println("END ASM");
639
640 //FIXME: Emit goto forwarder code here
591 } 641 }
592 642
593 // the whole idea of this statement is to avoid the flattening 643 // the whole idea of this statement is to avoid the flattening
594 Statements* AsmBlockStatement::flatten(Scope* sc) 644 Statements* AsmBlockStatement::flatten(Scope* sc)
595 { 645 {