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