1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! Adapter for a `MachBackend` to implement the `TargetIsa` trait.

use crate::binemit;
use crate::ir;
use crate::isa::{EncInfo, Encoding, Encodings, Legalize, RegClass, RegInfo, TargetIsa};
use crate::machinst::*;
use crate::regalloc::RegisterSet;
use crate::settings::Flags;

#[cfg(feature = "testing_hooks")]
use crate::regalloc::RegDiversions;

use std::borrow::Cow;
use std::fmt;
use target_lexicon::Triple;

/// A wrapper around a `MachBackend` that provides a `TargetIsa` impl.
pub struct TargetIsaAdapter {
    backend: Box<dyn MachBackend + Send + Sync + 'static>,
    triple: Triple,
}

impl TargetIsaAdapter {
    /// Create a new `TargetIsa` wrapper around a `MachBackend`.
    pub fn new<B: MachBackend + Send + Sync + 'static>(backend: B) -> TargetIsaAdapter {
        let triple = backend.triple();
        TargetIsaAdapter {
            backend: Box::new(backend),
            triple,
        }
    }
}

impl fmt::Display for TargetIsaAdapter {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("MachBackend")
            .field("name", &self.backend.name())
            .field("triple", &self.backend.triple())
            .field("flags", &format!("{}", self.backend.flags()))
            .finish()
    }
}

impl TargetIsa for TargetIsaAdapter {
    fn name(&self) -> &'static str {
        self.backend.name()
    }

    fn triple(&self) -> &Triple {
        &self.triple
    }

    fn flags(&self) -> &Flags {
        self.backend.flags()
    }

    fn register_info(&self) -> RegInfo {
        // Called from function's Display impl, so we need a stub here.
        RegInfo {
            banks: &[],
            classes: &[],
        }
    }

    fn legal_encodings<'a>(
        &'a self,
        _func: &'a ir::Function,
        _inst: &'a ir::InstructionData,
        _ctrl_typevar: ir::Type,
    ) -> Encodings<'a> {
        panic!("Should not be called when new-style backend is available!")
    }

    fn encode(
        &self,
        _func: &ir::Function,
        _inst: &ir::InstructionData,
        _ctrl_typevar: ir::Type,
    ) -> Result<Encoding, Legalize> {
        panic!("Should not be called when new-style backend is available!")
    }

    fn encoding_info(&self) -> EncInfo {
        panic!("Should not be called when new-style backend is available!")
    }

    fn legalize_signature(&self, _sig: &mut Cow<ir::Signature>, _current: bool) {
        panic!("Should not be called when new-style backend is available!")
    }

    fn regclass_for_abi_type(&self, _ty: ir::Type) -> RegClass {
        panic!("Should not be called when new-style backend is available!")
    }

    fn allocatable_registers(&self, _func: &ir::Function) -> RegisterSet {
        panic!("Should not be called when new-style backend is available!")
    }

    fn prologue_epilogue(&self, _func: &mut ir::Function) -> CodegenResult<()> {
        panic!("Should not be called when new-style backend is available!")
    }

    #[cfg(feature = "testing_hooks")]
    fn emit_inst(
        &self,
        _func: &ir::Function,
        _inst: ir::Inst,
        _divert: &mut RegDiversions,
        _sink: &mut dyn binemit::CodeSink,
    ) {
        panic!("Should not be called when new-style backend is available!")
    }

    /// Emit a whole function into memory.
    fn emit_function_to_memory(&self, _func: &ir::Function, _sink: &mut binemit::MemoryCodeSink) {
        panic!("Should not be called when new-style backend is available!")
    }

    fn get_mach_backend(&self) -> Option<&dyn MachBackend> {
        Some(&*self.backend)
    }

    fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
        self.backend.unsigned_add_overflow_condition()
    }

    fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC {
        self.backend.unsigned_sub_overflow_condition()
    }
}