1 //! x86 Instruction Set Architectures.
2
3 mod abi;
4 mod binemit;
5 mod enc_tables;
6 mod registers;
7 pub mod settings;
8 #[cfg(feature = "unwind")]
9 pub mod unwind;
10
11 use super::super::settings as shared_settings;
12 #[cfg(feature = "testing_hooks")]
13 use crate::binemit::CodeSink;
14 use crate::binemit::{emit_function, MemoryCodeSink};
15 use crate::ir;
16 use crate::isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings};
17 use crate::isa::Builder as IsaBuilder;
18 #[cfg(feature = "unwind")]
19 use crate::isa::{unwind::systemv::RegisterMappingError, RegUnit};
20 use crate::isa::{EncInfo, RegClass, RegInfo, TargetIsa};
21 use crate::regalloc;
22 use crate::result::CodegenResult;
23 use crate::timing;
24 use alloc::borrow::Cow;
25 use alloc::boxed::Box;
26 use core::fmt;
27 use target_lexicon::{PointerWidth, Triple};
28
29 #[allow(dead_code)]
30 struct Isa {
31 triple: Triple,
32 shared_flags: shared_settings::Flags,
33 isa_flags: settings::Flags,
34 cpumode: &'static [shared_enc_tables::Level1Entry<u16>],
35 }
36
37 /// Get an ISA builder for creating x86 targets.
isa_builder(triple: Triple) -> IsaBuilder38 pub fn isa_builder(triple: Triple) -> IsaBuilder {
39 IsaBuilder {
40 triple,
41 setup: settings::builder(),
42 constructor: isa_constructor,
43 }
44 }
45
isa_constructor( triple: Triple, shared_flags: shared_settings::Flags, builder: shared_settings::Builder, ) -> Box<dyn TargetIsa>46 fn isa_constructor(
47 triple: Triple,
48 shared_flags: shared_settings::Flags,
49 builder: shared_settings::Builder,
50 ) -> Box<dyn TargetIsa> {
51 let level1 = match triple.pointer_width().unwrap() {
52 PointerWidth::U16 => unimplemented!("x86-16"),
53 PointerWidth::U32 => &enc_tables::LEVEL1_I32[..],
54 PointerWidth::U64 => &enc_tables::LEVEL1_I64[..],
55 };
56 Box::new(Isa {
57 triple,
58 isa_flags: settings::Flags::new(&shared_flags, builder),
59 shared_flags,
60 cpumode: level1,
61 })
62 }
63
64 impl TargetIsa for Isa {
name(&self) -> &'static str65 fn name(&self) -> &'static str {
66 "x86"
67 }
68
triple(&self) -> &Triple69 fn triple(&self) -> &Triple {
70 &self.triple
71 }
72
flags(&self) -> &shared_settings::Flags73 fn flags(&self) -> &shared_settings::Flags {
74 &self.shared_flags
75 }
76
uses_cpu_flags(&self) -> bool77 fn uses_cpu_flags(&self) -> bool {
78 true
79 }
80
uses_complex_addresses(&self) -> bool81 fn uses_complex_addresses(&self) -> bool {
82 true
83 }
84
register_info(&self) -> RegInfo85 fn register_info(&self) -> RegInfo {
86 registers::INFO.clone()
87 }
88
89 #[cfg(feature = "unwind")]
map_dwarf_register(&self, reg: RegUnit) -> Result<u16, RegisterMappingError>90 fn map_dwarf_register(&self, reg: RegUnit) -> Result<u16, RegisterMappingError> {
91 unwind::systemv::map_reg(self, reg).map(|r| r.0)
92 }
93
encoding_info(&self) -> EncInfo94 fn encoding_info(&self) -> EncInfo {
95 enc_tables::INFO.clone()
96 }
97
legal_encodings<'a>( &'a self, func: &'a ir::Function, inst: &'a ir::InstructionData, ctrl_typevar: ir::Type, ) -> Encodings<'a>98 fn legal_encodings<'a>(
99 &'a self,
100 func: &'a ir::Function,
101 inst: &'a ir::InstructionData,
102 ctrl_typevar: ir::Type,
103 ) -> Encodings<'a> {
104 lookup_enclist(
105 ctrl_typevar,
106 inst,
107 func,
108 self.cpumode,
109 &enc_tables::LEVEL2[..],
110 &enc_tables::ENCLISTS[..],
111 &enc_tables::LEGALIZE_ACTIONS[..],
112 &enc_tables::RECIPE_PREDICATES[..],
113 &enc_tables::INST_PREDICATES[..],
114 self.isa_flags.predicate_view(),
115 )
116 }
117
legalize_signature(&self, sig: &mut Cow<ir::Signature>, current: bool)118 fn legalize_signature(&self, sig: &mut Cow<ir::Signature>, current: bool) {
119 abi::legalize_signature(
120 sig,
121 &self.triple,
122 current,
123 &self.shared_flags,
124 &self.isa_flags,
125 )
126 }
127
regclass_for_abi_type(&self, ty: ir::Type) -> RegClass128 fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass {
129 abi::regclass_for_abi_type(ty)
130 }
131
allocatable_registers(&self, _func: &ir::Function) -> regalloc::RegisterSet132 fn allocatable_registers(&self, _func: &ir::Function) -> regalloc::RegisterSet {
133 abi::allocatable_registers(&self.triple, &self.shared_flags)
134 }
135
136 #[cfg(feature = "testing_hooks")]
emit_inst( &self, func: &ir::Function, inst: ir::Inst, divert: &mut regalloc::RegDiversions, sink: &mut dyn CodeSink, )137 fn emit_inst(
138 &self,
139 func: &ir::Function,
140 inst: ir::Inst,
141 divert: &mut regalloc::RegDiversions,
142 sink: &mut dyn CodeSink,
143 ) {
144 binemit::emit_inst(func, inst, divert, sink, self)
145 }
146
emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink)147 fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
148 emit_function(func, binemit::emit_inst, sink, self)
149 }
150
prologue_epilogue(&self, func: &mut ir::Function) -> CodegenResult<()>151 fn prologue_epilogue(&self, func: &mut ir::Function) -> CodegenResult<()> {
152 let _tt = timing::prologue_epilogue();
153 abi::prologue_epilogue(func, self)
154 }
155
unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC156 fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
157 ir::condcodes::IntCC::UnsignedLessThan
158 }
159
unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC160 fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC {
161 ir::condcodes::IntCC::UnsignedLessThan
162 }
163
164 #[cfg(feature = "unwind")]
create_unwind_info( &self, func: &ir::Function, ) -> CodegenResult<Option<super::unwind::UnwindInfo>>165 fn create_unwind_info(
166 &self,
167 func: &ir::Function,
168 ) -> CodegenResult<Option<super::unwind::UnwindInfo>> {
169 abi::create_unwind_info(func, self)
170 }
171
172 #[cfg(feature = "unwind")]
create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry>173 fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {
174 Some(unwind::systemv::create_cie())
175 }
176 }
177
178 impl fmt::Display for Isa {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result179 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
180 write!(f, "{}\n{}", self.shared_flags, self.isa_flags)
181 }
182 }
183