|
11 | 11 | use core::prelude::*;
|
12 | 12 |
|
13 | 13 | use back::{link, abi};
|
14 |
| -use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; |
15 | 14 | use lib::llvm::{TypeRef, ValueRef};
|
16 | 15 | use lib;
|
17 | 16 | use middle::trans::base::*;
|
@@ -578,118 +577,73 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
|
578 | 577 | let mut bcx = top_scope_block(fcx, None);
|
579 | 578 | let lltop = bcx.llbb;
|
580 | 579 | let first_real_arg = fcx.arg_pos(0u);
|
581 |
| - match ccx.sess.str_of(item.ident).as_slice() { |
582 |
| - "atomic_cxchg" => { |
583 |
| - let old = AtomicCmpXchg(bcx, |
584 |
| - get_param(decl, first_real_arg), |
585 |
| - get_param(decl, first_real_arg + 1u), |
586 |
| - get_param(decl, first_real_arg + 2u), |
587 |
| - SequentiallyConsistent); |
588 |
| - Store(bcx, old, fcx.llretptr.get()); |
589 |
| - } |
590 |
| - "atomic_cxchg_acq" => { |
591 |
| - let old = AtomicCmpXchg(bcx, |
592 |
| - get_param(decl, first_real_arg), |
593 |
| - get_param(decl, first_real_arg + 1u), |
594 |
| - get_param(decl, first_real_arg + 2u), |
595 |
| - Acquire); |
596 |
| - Store(bcx, old, fcx.llretptr.get()); |
597 |
| - } |
598 |
| - "atomic_cxchg_rel" => { |
599 |
| - let old = AtomicCmpXchg(bcx, |
600 |
| - get_param(decl, first_real_arg), |
| 580 | + |
| 581 | + let nm = ccx.sess.str_of(item.ident); |
| 582 | + let name = nm.as_slice(); |
| 583 | + |
| 584 | + // This requires that atomic intrinsics follow a specific naming pattern: |
| 585 | + // "atomic_<operation>[_<ordering>], and no ordering means SeqCst |
| 586 | + if name.starts_with("atomic_") { |
| 587 | + let split : ~[&str] = name.split_iter('_').collect(); |
| 588 | + assert!(split.len() >= 2, "Atomic intrinsic not correct format"); |
| 589 | + let order = if split.len() == 2 { |
| 590 | + lib::llvm::SequentiallyConsistent |
| 591 | + } else { |
| 592 | + match split[2] { |
| 593 | + "relaxed" => lib::llvm::Monotonic, |
| 594 | + "acq" => lib::llvm::Acquire, |
| 595 | + "rel" => lib::llvm::Release, |
| 596 | + "acqrel" => lib::llvm::AcquireRelease, |
| 597 | + _ => ccx.sess.fatal("Unknown ordering in atomic intrinsic") |
| 598 | + } |
| 599 | + }; |
| 600 | + |
| 601 | + match split[1] { |
| 602 | + "cxchg" => { |
| 603 | + let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg), |
| 604 | + get_param(decl, first_real_arg + 1u), |
| 605 | + get_param(decl, first_real_arg + 2u), |
| 606 | + order); |
| 607 | + Store(bcx, old, fcx.llretptr.get()); |
| 608 | + } |
| 609 | + "load" => { |
| 610 | + let old = AtomicLoad(bcx, get_param(decl, first_real_arg), |
| 611 | + order); |
| 612 | + Store(bcx, old, fcx.llretptr.get()); |
| 613 | + } |
| 614 | + "store" => { |
| 615 | + AtomicStore(bcx, get_param(decl, first_real_arg + 1u), |
| 616 | + get_param(decl, first_real_arg), |
| 617 | + order); |
| 618 | + } |
| 619 | + op => { |
| 620 | + // These are all AtomicRMW ops |
| 621 | + let atom_op = match op { |
| 622 | + "xchg" => lib::llvm::Xchg, |
| 623 | + "xadd" => lib::llvm::Add, |
| 624 | + "xsub" => lib::llvm::Sub, |
| 625 | + "and" => lib::llvm::And, |
| 626 | + "nand" => lib::llvm::Nand, |
| 627 | + "or" => lib::llvm::Or, |
| 628 | + "xor" => lib::llvm::Xor, |
| 629 | + "max" => lib::llvm::Max, |
| 630 | + "min" => lib::llvm::Min, |
| 631 | + "umax" => lib::llvm::UMax, |
| 632 | + "umin" => lib::llvm::UMin, |
| 633 | + _ => ccx.sess.fatal("Unknown atomic operation") |
| 634 | + }; |
| 635 | + |
| 636 | + let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg), |
601 | 637 | get_param(decl, first_real_arg + 1u),
|
602 |
| - get_param(decl, first_real_arg + 2u), |
603 |
| - Release); |
604 |
| - Store(bcx, old, fcx.llretptr.get()); |
605 |
| - } |
606 |
| - "atomic_load" => { |
607 |
| - let old = AtomicLoad(bcx, |
608 |
| - get_param(decl, first_real_arg), |
609 |
| - SequentiallyConsistent); |
610 |
| - Store(bcx, old, fcx.llretptr.get()); |
611 |
| - } |
612 |
| - "atomic_load_acq" => { |
613 |
| - let old = AtomicLoad(bcx, |
614 |
| - get_param(decl, first_real_arg), |
615 |
| - Acquire); |
616 |
| - Store(bcx, old, fcx.llretptr.get()); |
617 |
| - } |
618 |
| - "atomic_store" => { |
619 |
| - AtomicStore(bcx, |
620 |
| - get_param(decl, first_real_arg + 1u), |
621 |
| - get_param(decl, first_real_arg), |
622 |
| - SequentiallyConsistent); |
623 |
| - } |
624 |
| - "atomic_store_rel" => { |
625 |
| - AtomicStore(bcx, |
626 |
| - get_param(decl, first_real_arg + 1u), |
627 |
| - get_param(decl, first_real_arg), |
628 |
| - Release); |
629 |
| - } |
630 |
| - "atomic_xchg" => { |
631 |
| - let old = AtomicRMW(bcx, Xchg, |
632 |
| - get_param(decl, first_real_arg), |
633 |
| - get_param(decl, first_real_arg + 1u), |
634 |
| - SequentiallyConsistent); |
635 |
| - Store(bcx, old, fcx.llretptr.get()); |
636 |
| - } |
637 |
| - "atomic_xchg_acq" => { |
638 |
| - let old = AtomicRMW(bcx, Xchg, |
639 |
| - get_param(decl, first_real_arg), |
640 |
| - get_param(decl, first_real_arg + 1u), |
641 |
| - Acquire); |
642 |
| - Store(bcx, old, fcx.llretptr.get()); |
643 |
| - } |
644 |
| - "atomic_xchg_rel" => { |
645 |
| - let old = AtomicRMW(bcx, Xchg, |
646 |
| - get_param(decl, first_real_arg), |
647 |
| - get_param(decl, first_real_arg + 1u), |
648 |
| - Release); |
649 |
| - Store(bcx, old, fcx.llretptr.get()); |
650 |
| - } |
651 |
| - "atomic_xadd" => { |
652 |
| - let old = AtomicRMW(bcx, lib::llvm::Add, |
653 |
| - get_param(decl, first_real_arg), |
654 |
| - get_param(decl, first_real_arg + 1u), |
655 |
| - SequentiallyConsistent); |
656 |
| - Store(bcx, old, fcx.llretptr.get()); |
657 |
| - } |
658 |
| - "atomic_xadd_acq" => { |
659 |
| - let old = AtomicRMW(bcx, lib::llvm::Add, |
660 |
| - get_param(decl, first_real_arg), |
661 |
| - get_param(decl, first_real_arg + 1u), |
662 |
| - Acquire); |
663 |
| - Store(bcx, old, fcx.llretptr.get()); |
664 |
| - } |
665 |
| - "atomic_xadd_rel" => { |
666 |
| - let old = AtomicRMW(bcx, lib::llvm::Add, |
667 |
| - get_param(decl, first_real_arg), |
668 |
| - get_param(decl, first_real_arg + 1u), |
669 |
| - Release); |
670 |
| - Store(bcx, old, fcx.llretptr.get()); |
671 |
| - } |
672 |
| - "atomic_xsub" => { |
673 |
| - let old = AtomicRMW(bcx, lib::llvm::Sub, |
674 |
| - get_param(decl, first_real_arg), |
675 |
| - get_param(decl, first_real_arg + 1u), |
676 |
| - SequentiallyConsistent); |
677 |
| - Store(bcx, old, fcx.llretptr.get()); |
678 |
| - } |
679 |
| - "atomic_xsub_acq" => { |
680 |
| - let old = AtomicRMW(bcx, lib::llvm::Sub, |
681 |
| - get_param(decl, first_real_arg), |
682 |
| - get_param(decl, first_real_arg + 1u), |
683 |
| - Acquire); |
684 |
| - Store(bcx, old, fcx.llretptr.get()); |
685 |
| - } |
686 |
| - "atomic_xsub_rel" => { |
687 |
| - let old = AtomicRMW(bcx, lib::llvm::Sub, |
688 |
| - get_param(decl, first_real_arg), |
689 |
| - get_param(decl, first_real_arg + 1u), |
690 |
| - Release); |
691 |
| - Store(bcx, old, fcx.llretptr.get()); |
| 638 | + order); |
| 639 | + Store(bcx, old, fcx.llretptr.get()); |
| 640 | + } |
692 | 641 | }
|
| 642 | + |
| 643 | + return; |
| 644 | + } |
| 645 | + |
| 646 | + match name { |
693 | 647 | "size_of" => {
|
694 | 648 | let tp_ty = substs.tys[0];
|
695 | 649 | let lltp_ty = type_of::type_of(ccx, tp_ty);
|
|
0 commit comments