1 //! Adapter for a `MachBackend` to implement the `TargetIsa` trait. 2 3 use crate::binemit; 4 use crate::ir; 5 use crate::isa::{ 6 BackendVariant, EncInfo, Encoding, Encodings, Legalize, RegClass, RegInfo, TargetIsa, 7 }; 8 use crate::machinst::*; 9 use crate::regalloc::RegisterSet; 10 use crate::settings::{self, Flags}; 11 12 #[cfg(feature = "testing_hooks")] 13 use crate::regalloc::RegDiversions; 14 15 #[cfg(feature = "unwind")] 16 use crate::isa::unwind::systemv::RegisterMappingError; 17 18 use core::any::Any; 19 use std::borrow::Cow; 20 use std::fmt; 21 use target_lexicon::Triple; 22 23 /// A wrapper around a `MachBackend` that provides a `TargetIsa` impl. 24 pub struct TargetIsaAdapter { 25 backend: Box<dyn MachBackend + Send + Sync + 'static>, 26 triple: Triple, 27 } 28 29 impl TargetIsaAdapter { 30 /// Create a new `TargetIsa` wrapper around a `MachBackend`. new<B: MachBackend + Send + Sync + 'static>(backend: B) -> TargetIsaAdapter31 pub fn new<B: MachBackend + Send + Sync + 'static>(backend: B) -> TargetIsaAdapter { 32 let triple = backend.triple(); 33 TargetIsaAdapter { 34 backend: Box::new(backend), 35 triple, 36 } 37 } 38 } 39 40 impl fmt::Display for TargetIsaAdapter { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 42 f.debug_struct("MachBackend") 43 .field("name", &self.backend.name()) 44 .field("triple", &self.backend.triple()) 45 .field("flags", &format!("{}", self.backend.flags())) 46 .finish() 47 } 48 } 49 50 impl TargetIsa for TargetIsaAdapter { name(&self) -> &'static str51 fn name(&self) -> &'static str { 52 self.backend.name() 53 } 54 triple(&self) -> &Triple55 fn triple(&self) -> &Triple { 56 &self.triple 57 } 58 flags(&self) -> &Flags59 fn flags(&self) -> &Flags { 60 self.backend.flags() 61 } 62 isa_flags(&self) -> Vec<settings::Value>63 fn isa_flags(&self) -> Vec<settings::Value> { 64 self.backend.isa_flags() 65 } 66 variant(&self) -> BackendVariant67 fn variant(&self) -> BackendVariant { 68 BackendVariant::MachInst 69 } 70 hash_all_flags(&self, hasher: &mut dyn Hasher)71 fn hash_all_flags(&self, hasher: &mut dyn Hasher) { 72 self.backend.hash_all_flags(hasher); 73 } 74 register_info(&self) -> RegInfo75 fn register_info(&self) -> RegInfo { 76 // Called from function's Display impl, so we need a stub here. 77 RegInfo { 78 banks: &[], 79 classes: &[], 80 } 81 } 82 legal_encodings<'a>( &'a self, _func: &'a ir::Function, _inst: &'a ir::InstructionData, _ctrl_typevar: ir::Type, ) -> Encodings<'a>83 fn legal_encodings<'a>( 84 &'a self, 85 _func: &'a ir::Function, 86 _inst: &'a ir::InstructionData, 87 _ctrl_typevar: ir::Type, 88 ) -> Encodings<'a> { 89 panic!("Should not be called when new-style backend is available!") 90 } 91 encode( &self, _func: &ir::Function, _inst: &ir::InstructionData, _ctrl_typevar: ir::Type, ) -> Result<Encoding, Legalize>92 fn encode( 93 &self, 94 _func: &ir::Function, 95 _inst: &ir::InstructionData, 96 _ctrl_typevar: ir::Type, 97 ) -> Result<Encoding, Legalize> { 98 panic!("Should not be called when new-style backend is available!") 99 } 100 encoding_info(&self) -> EncInfo101 fn encoding_info(&self) -> EncInfo { 102 panic!("Should not be called when new-style backend is available!") 103 } 104 legalize_signature(&self, _sig: &mut Cow<ir::Signature>, _current: bool)105 fn legalize_signature(&self, _sig: &mut Cow<ir::Signature>, _current: bool) { 106 panic!("Should not be called when new-style backend is available!") 107 } 108 regclass_for_abi_type(&self, _ty: ir::Type) -> RegClass109 fn regclass_for_abi_type(&self, _ty: ir::Type) -> RegClass { 110 panic!("Should not be called when new-style backend is available!") 111 } 112 allocatable_registers(&self, _func: &ir::Function) -> RegisterSet113 fn allocatable_registers(&self, _func: &ir::Function) -> RegisterSet { 114 panic!("Should not be called when new-style backend is available!") 115 } 116 prologue_epilogue(&self, _func: &mut ir::Function) -> CodegenResult<()>117 fn prologue_epilogue(&self, _func: &mut ir::Function) -> CodegenResult<()> { 118 panic!("Should not be called when new-style backend is available!") 119 } 120 121 #[cfg(feature = "testing_hooks")] emit_inst( &self, _func: &ir::Function, _inst: ir::Inst, _divert: &mut RegDiversions, _sink: &mut dyn binemit::CodeSink, )122 fn emit_inst( 123 &self, 124 _func: &ir::Function, 125 _inst: ir::Inst, 126 _divert: &mut RegDiversions, 127 _sink: &mut dyn binemit::CodeSink, 128 ) { 129 panic!("Should not be called when new-style backend is available!") 130 } 131 132 /// Emit a whole function into memory. emit_function_to_memory(&self, _func: &ir::Function, _sink: &mut binemit::MemoryCodeSink)133 fn emit_function_to_memory(&self, _func: &ir::Function, _sink: &mut binemit::MemoryCodeSink) { 134 panic!("Should not be called when new-style backend is available!") 135 } 136 get_mach_backend(&self) -> Option<&dyn MachBackend>137 fn get_mach_backend(&self) -> Option<&dyn MachBackend> { 138 Some(&*self.backend) 139 } 140 unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC141 fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC { 142 self.backend.unsigned_add_overflow_condition() 143 } 144 unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC145 fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC { 146 self.backend.unsigned_sub_overflow_condition() 147 } 148 149 #[cfg(feature = "unwind")] create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry>150 fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> { 151 self.backend.create_systemv_cie() 152 } 153 154 #[cfg(feature = "unwind")] map_regalloc_reg_to_dwarf(&self, r: Reg) -> Result<u16, RegisterMappingError>155 fn map_regalloc_reg_to_dwarf(&self, r: Reg) -> Result<u16, RegisterMappingError> { 156 self.backend.map_reg_to_dwarf(r) 157 } 158 as_any(&self) -> &dyn Any159 fn as_any(&self) -> &dyn Any { 160 self as &dyn Any 161 } 162 } 163