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
mod relaxation;
mod memorysink;
pub use regalloc::RegDiversions;
pub use self::relaxation::relax_branches;
pub use self::memorysink::{MemoryCodeSink, RelocSink};
use ir::{ExternalName, JumpTable, Function, Inst};
use std::fmt;
pub type CodeOffset = u32;
pub type Addend = i64;
#[derive(Debug)]
pub enum Reloc {
IntelPCRel4,
IntelAbs4,
IntelAbs8,
IntelGOTPCRel4,
IntelPLTRel4,
Arm32Call,
Arm64Call,
RiscvCall,
}
impl fmt::Display for Reloc {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Reloc::IntelPCRel4 => write!(f, "{}", "PCRel4"),
Reloc::IntelAbs4 => write!(f, "{}", "Abs4"),
Reloc::IntelAbs8 => write!(f, "{}", "Abs8"),
Reloc::IntelGOTPCRel4 => write!(f, "{}", "GOTPCRel4"),
Reloc::IntelPLTRel4 => write!(f, "{}", "PLTRel4"),
Reloc::Arm32Call | Reloc::Arm64Call | Reloc::RiscvCall => write!(f, "{}", "Call"),
}
}
}
pub trait CodeSink {
fn offset(&self) -> CodeOffset;
fn put1(&mut self, u8);
fn put2(&mut self, u16);
fn put4(&mut self, u32);
fn put8(&mut self, u64);
fn reloc_ebb(&mut self, Reloc, CodeOffset);
fn reloc_external(&mut self, Reloc, &ExternalName, Addend);
fn reloc_jt(&mut self, Reloc, JumpTable);
}
#[inline(never)]
pub fn bad_encoding(func: &Function, inst: Inst) -> ! {
panic!(
"Bad encoding {} for {}",
func.encodings[inst],
func.dfg.display_inst(inst, None)
);
}
pub fn emit_function<CS, EI>(func: &Function, emit_inst: EI, sink: &mut CS)
where
CS: CodeSink,
EI: Fn(&Function, Inst, &mut RegDiversions, &mut CS),
{
let mut divert = RegDiversions::new();
for ebb in func.layout.ebbs() {
divert.clear();
debug_assert_eq!(func.offsets[ebb], sink.offset());
for inst in func.layout.ebb_insts(ebb) {
emit_inst(func, inst, &mut divert, sink);
}
}
}