To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

codegen.rs 10 KB
Newer Older
1
2
use ast::ptr::P;
use ast::ir::*;
qinsoon's avatar
qinsoon committed
3
use runtime::ValueLocation;
4

qinsoon's avatar
qinsoon committed
5
use compiler::machine_code::MachineCode;
qinsoon's avatar
qinsoon committed
6
use compiler::backend::{Reg, Mem};
7

8
pub trait CodeGenerator {
9
    fn start_code(&mut self, func_name: MuName, entry: MuName) -> ValueLocation;
10
    fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode + Sync + Send>, ValueLocation);
11
12
13
14

    // generate unnamed sequence of linear code (no branch)
    fn start_code_sequence(&mut self);
    fn finish_code_sequence(&mut self) -> Box<MachineCode + Sync + Send>;
qinsoon's avatar
qinsoon committed
15
16
17
    
    fn print_cur_code(&self);
    
qinsoon's avatar
qinsoon committed
18
    fn start_block(&mut self, block_name: MuName);
qinsoon's avatar
qinsoon committed
19
    fn start_exception_block(&mut self, block_name: MuName) -> ValueLocation;
qinsoon's avatar
qinsoon committed
20
21
22
    fn set_block_livein(&mut self, block_name: MuName, live_in: &Vec<P<Value>>);
    fn set_block_liveout(&mut self, block_name: MuName, live_out: &Vec<P<Value>>);
    fn end_block(&mut self, block_name: MuName);
qinsoon's avatar
qinsoon committed
23

qinsoon's avatar
qinsoon committed
24
25
26
27
28
29
30
31
    // add CFI info
    fn add_cfi_startproc(&mut self);
    fn add_cfi_endproc(&mut self);
    fn add_cfi_def_cfa_register(&mut self, reg: Reg);
    fn add_cfi_def_cfa_offset(&mut self, offset: i32);
    fn add_cfi_offset(&mut self, reg: Reg, offset: i32);

    // emit code to adjust frame
qinsoon's avatar
qinsoon committed
32
33
    fn emit_frame_grow(&mut self);
    fn emit_frame_shrink(&mut self);
qinsoon's avatar
qinsoon committed
34
    
qinsoon's avatar
qinsoon committed
35
    fn emit_nop(&mut self, bytes: usize);
36
37

    // comparison
qinsoon's avatar
qinsoon committed
38
39
40
    fn emit_cmp_r_r  (&mut self, op1: Reg, op2: Reg);
    fn emit_cmp_imm_r(&mut self, op1: i32, op2: Reg);
    fn emit_cmp_mem_r(&mut self, op1: Reg, op2: Reg);
41

qinsoon's avatar
qinsoon committed
42
43
    fn emit_test_r_r (&mut self, op1: Reg, op2: Reg);

44
    // gpr move
qinsoon's avatar
qinsoon committed
45
46

    // mov imm64 to r64
47
    fn emit_mov_r64_imm64  (&mut self, dest: Reg, src: i64);
qinsoon's avatar
qinsoon committed
48
49
    // mov r64 to fpr
    fn emit_mov_fpr_r64 (&mut self, dest: Reg, src: Reg);
qinsoon's avatar
qinsoon committed
50
51
52
53
54

    fn emit_mov_r_imm  (&mut self, dest: Reg, src: i32);
    fn emit_mov_r_mem  (&mut self, dest: Reg, src: Mem); // load
    fn emit_mov_r_r    (&mut self, dest: Reg, src: Reg);
    fn emit_mov_mem_r  (&mut self, dest: Mem, src: Reg); // store
55
56
57
    // we can infer imm length from Reg, but cannot from Mem
    // because mem may only have type as ADDRESS_TYPE
    fn emit_mov_mem_imm(&mut self, dest: Mem, src: i32, oplen: usize); // store
qinsoon's avatar
qinsoon committed
58
59
60
61

    // zero/sign extend mov
    fn emit_movs_r_r   (&mut self, dest: Reg, src: Reg);
    fn emit_movz_r_r   (&mut self, dest: Reg, src: Reg);
62

qinsoon's avatar
qinsoon committed
63
64
65
66
67
68
    // set byte
    fn emit_sets_r8    (&mut self, dest: Reg);
    fn emit_setz_r8    (&mut self, dest: Reg);
    fn emit_seto_r8    (&mut self, dest: Reg);
    fn emit_setb_r8    (&mut self, dest: Reg);

69
70
71
72
73
74
75
76
77
78
79
    fn emit_seta_r  (&mut self, dest: Reg);
    fn emit_setae_r  (&mut self, dest: Reg);
    fn emit_setb_r  (&mut self, dest: Reg);
    fn emit_setbe_r  (&mut self, dest: Reg);
    fn emit_sete_r  (&mut self, dest: Reg);
    fn emit_setg_r  (&mut self, dest: Reg);
    fn emit_setge_r  (&mut self, dest: Reg);
    fn emit_setl_r  (&mut self, dest: Reg);
    fn emit_setle_r  (&mut self, dest: Reg);
    fn emit_setne_r  (&mut self, dest: Reg);

qinsoon's avatar
qinsoon committed
80
81
    // gpr conditional move

qinsoon's avatar
qinsoon committed
82
83
    fn emit_cmova_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmova_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
84

qinsoon's avatar
qinsoon committed
85
86
    fn emit_cmovae_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovae_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
87

qinsoon's avatar
qinsoon committed
88
89
    fn emit_cmovb_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovb_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
90

qinsoon's avatar
qinsoon committed
91
92
    fn emit_cmovbe_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovbe_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
93

qinsoon's avatar
qinsoon committed
94
95
    fn emit_cmove_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmove_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
96

qinsoon's avatar
qinsoon committed
97
98
    fn emit_cmovg_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovg_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
99

qinsoon's avatar
qinsoon committed
100
101
    fn emit_cmovge_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovge_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
102

qinsoon's avatar
qinsoon committed
103
104
    fn emit_cmovl_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovl_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
105

qinsoon's avatar
qinsoon committed
106
107
    fn emit_cmovle_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovle_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
108

qinsoon's avatar
qinsoon committed
109
110
    fn emit_cmovne_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cmovne_r_mem(&mut self, dest: Reg, src: Mem); // load
qinsoon's avatar
qinsoon committed
111

112
    // lea
qinsoon's avatar
qinsoon committed
113
    fn emit_lea_r64(&mut self, dest: Reg, src: Mem);
114
115

    // and
qinsoon's avatar
qinsoon committed
116
117
118
    fn emit_and_r_imm(&mut self, dest: Reg, src: i32);
    fn emit_and_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_and_r_mem(&mut self, dest: Reg, src: Mem);
119

qinsoon's avatar
qinsoon committed
120
121
122
123
    // or
    fn emit_or_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_or_r_imm(&mut self, dest: Reg, src: i32);
    fn emit_or_r_mem(&mut self, dest: Reg, src: Mem);
qinsoon's avatar
qinsoon committed
124

125
    // xor
qinsoon's avatar
qinsoon committed
126
127
128
    fn emit_xor_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_xor_r_mem(&mut self, dest: Reg, src: Mem);
    fn emit_xor_r_imm(&mut self, dest: Reg, src: i32);
129

130
    // add
qinsoon's avatar
qinsoon committed
131
132
133
    fn emit_add_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_add_r_mem(&mut self, dest: Reg, src: Mem);
    fn emit_add_r_imm(&mut self, dest: Reg, src: i32);
qinsoon's avatar
qinsoon committed
134
135
136
137
138

    // add with carry
    fn emit_adc_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_adc_r_mem(&mut self, dest: Reg, src: Mem);
    fn emit_adc_r_imm(&mut self, dest: Reg, src: i32);
qinsoon's avatar
qinsoon committed
139
    
140
    // sub
qinsoon's avatar
qinsoon committed
141
142
143
    fn emit_sub_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_sub_r_mem(&mut self, dest: Reg, src: Mem);
    fn emit_sub_r_imm(&mut self, dest: Reg, src: i32);
144

145
146
147
148
149
    // sub with borrow
    fn emit_sbb_r_r  (&mut self, dest: Reg, src: Reg);
    fn emit_sbb_r_mem(&mut self, dest: Reg, src: Mem);
    fn emit_sbb_r_imm(&mut self, dest: Reg, src: i32);

150
    // multiply
qinsoon's avatar
qinsoon committed
151
152
    fn emit_mul_r  (&mut self, src: Reg);
    fn emit_mul_mem(&mut self, src: Mem);
153

154
155
156
    // signed multiply
    fn emit_imul_r_r(&mut self, dest: Reg, src: Reg);

157
    // div
qinsoon's avatar
qinsoon committed
158
159
    fn emit_div_r   (&mut self, src: Reg);
    fn emit_div_mem (&mut self, src: Mem);
160
161

    // idiv
qinsoon's avatar
qinsoon committed
162
163
    fn emit_idiv_r  (&mut self, src: Reg);
    fn emit_idiv_mem(&mut self, src: Mem);
164
165

    // shl
qinsoon's avatar
qinsoon committed
166
167
168
169
170
171
172
173
    fn emit_shl_r_cl    (&mut self, dest: Reg);
    fn emit_shl_r_imm8  (&mut self, dest: Reg, src: i8);

    fn emit_shr_r_cl    (&mut self, dest: &P<Value>);
    fn emit_shr_r_imm8  (&mut self, dest: &P<Value>, src: i8);

    fn emit_sar_r_cl    (&mut self, dest: &P<Value>);
    fn emit_sar_r_imm8  (&mut self, dest: &P<Value>, src: i8);
qinsoon's avatar
qinsoon committed
174

qinsoon's avatar
qinsoon committed
175
176
177
    fn emit_cqo(&mut self); // sign extend rax to rdx:rax
    fn emit_cdq(&mut self); // sign extend eax to edx:eax
    fn emit_cwd(&mut self); // sign extend ax  to dx:ax
178
    
179
180
181
182
183
184
185
186
187
188
189
    fn emit_jmp(&mut self, dest: MuName);
    fn emit_je(&mut self, dest: MuName);
    fn emit_jne(&mut self, dest: MuName);
    fn emit_ja(&mut self, dest: MuName);
    fn emit_jae(&mut self, dest: MuName);
    fn emit_jb(&mut self, dest: MuName);
    fn emit_jbe(&mut self, dest: MuName);
    fn emit_jg(&mut self, dest: MuName);
    fn emit_jge(&mut self, dest: MuName);
    fn emit_jl(&mut self, dest: MuName);
    fn emit_jle(&mut self, dest: MuName);
qinsoon's avatar
qinsoon committed
190
191

    fn emit_js(&mut self, dest: MuName);
qinsoon's avatar
qinsoon committed
192
    
193
194
195
    fn emit_call_near_rel32(&mut self, callsite: String, func: MuName,    pe: Option<MuName>) -> ValueLocation;
    fn emit_call_near_r64  (&mut self, callsite: String, func: &P<Value>, pe: Option<MuName>) -> ValueLocation;
    fn emit_call_near_mem64(&mut self, callsite: String, func: &P<Value>, pe: Option<MuName>) -> ValueLocation;
196
    
qinsoon's avatar
qinsoon committed
197
    fn emit_ret(&mut self);
qinsoon's avatar
qinsoon committed
198

qinsoon's avatar
qinsoon committed
199
    fn emit_push_r64(&mut self, src: &P<Value>);
200
    fn emit_push_imm32(&mut self, src: i32);
qinsoon's avatar
qinsoon committed
201
    fn emit_pop_r64(&mut self, dest: &P<Value>);
202
203
204
205
206

    // fpr move
    fn emit_movsd_f64_f64  (&mut self, dest: &P<Value>, src: &P<Value>);
    fn emit_movsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>); // load
    fn emit_movsd_mem64_f64(&mut self, dest: &P<Value>, src: &P<Value>); // store
qinsoon's avatar
qinsoon committed
207

208
209
210
211
    fn emit_movss_f32_f32  (&mut self, dest: &P<Value>, src: &P<Value>);
    fn emit_movss_f32_mem32(&mut self, dest: &P<Value>, src: &P<Value>); // load
    fn emit_movss_mem32_f32(&mut self, dest: &P<Value>, src: &P<Value>); // store

qinsoon's avatar
qinsoon committed
212
213
214
215
    // fp add
    fn emit_addsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem);

216
217
218
    fn emit_addss_f32_f32  (&mut self, dest: Reg, src: Reg);
    fn emit_addss_f32_mem32(&mut self, dest: Reg, src: Mem);

qinsoon's avatar
qinsoon committed
219
220
221
222
    // fp sub
    fn emit_subsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_subsd_f64_mem64(&mut self, dest: Reg, src: Mem);

223
224
225
    fn emit_subss_f32_f32  (&mut self, dest: Reg, src: Reg);
    fn emit_subss_f32_mem32(&mut self, dest: Reg, src: Mem);

qinsoon's avatar
qinsoon committed
226
227
228
229
    // fp div
    fn emit_divsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_divsd_f64_mem64(&mut self, dest: Reg, src: Mem);

230
231
232
    fn emit_divss_f32_f32  (&mut self, dest: Reg, src: Reg);
    fn emit_divss_f32_mem32(&mut self, dest: Reg, src: Mem);

qinsoon's avatar
qinsoon committed
233
234
235
236
    // fp mul
    fn emit_mulsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_mulsd_f64_mem64(&mut self, dest: Reg, src: Mem);

237
238
239
    fn emit_mulss_f32_f32  (&mut self, dest: Reg, src: Reg);
    fn emit_mulss_f32_mem32(&mut self, dest: Reg, src: Mem);

qinsoon's avatar
qinsoon committed
240
241
242
    // fp comparison
    fn emit_comisd_f64_f64  (&mut self, op1: Reg, op2: Reg);
    fn emit_ucomisd_f64_f64 (&mut self, op1: Reg, op2: Reg);
qinsoon's avatar
qinsoon committed
243

244
245
246
    fn emit_comiss_f32_f32  (&mut self, op1: Reg, op2: Reg);
    fn emit_ucomiss_f32_f32 (&mut self, op1: Reg, op2: Reg);

qinsoon's avatar
qinsoon committed
247
248
249
    // fp conversion
    fn emit_cvtsi2sd_f64_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cvtsd2si_r_f64  (&mut self, dest: Reg, src: Reg);
250
251
252

    fn emit_cvtsi2ss_f32_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cvtss2si_r_f32  (&mut self, dest: Reg, src: Reg);
253
254
255

    // used for unsigned int to fp conversion

256
    fn emit_cvttsd2si_r_f64 (&mut self, dest: Reg, src: Reg);
qinsoon's avatar
qinsoon committed
257
    fn emit_cvttss2si_r_f32 (&mut self, dest: Reg, src: Reg);
258

259
260
261
262
263
264
    // unpack low data - interleave low byte
    fn emit_punpckldq_f64_mem128(&mut self, dest: Reg, src: Mem);
    // substract packed double-fp
    fn emit_subpd_f64_mem128   (&mut self, dest: Reg, src: Mem);
    // packed double-fp horizontal add
    fn emit_haddpd_f64_f64     (&mut self, dest: Reg, src: Reg);
265
266
267
268

    // move aligned packed double-precision fp values
    fn emit_movapd_f64_mem128(&mut self, dest: Reg, src: Mem);
    fn emit_movapd_f64_f64   (&mut self, dest: Reg, src: Mem);
qinsoon's avatar
qinsoon committed
269
270

    fn emit_movaps_f32_f32   (&mut self, dest: Reg, src: Reg);
271
}