GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

codegen.rs 9.79 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>;
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);
34
    
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);
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

    // multiply
qinsoon's avatar
qinsoon committed
146 147
    fn emit_mul_r  (&mut self, src: Reg);
    fn emit_mul_mem(&mut self, src: Mem);
148 149

    // div
qinsoon's avatar
qinsoon committed
150 151
    fn emit_div_r   (&mut self, src: Reg);
    fn emit_div_mem (&mut self, src: Mem);
152 153

    // idiv
qinsoon's avatar
qinsoon committed
154 155
    fn emit_idiv_r  (&mut self, src: Reg);
    fn emit_idiv_mem(&mut self, src: Mem);
156 157

    // shl
qinsoon's avatar
qinsoon committed
158 159 160 161 162 163 164 165
    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
166

qinsoon's avatar
qinsoon committed
167 168 169
    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
170
    
171 172 173 174 175 176 177 178 179 180 181
    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
182 183

    fn emit_js(&mut self, dest: MuName);
qinsoon's avatar
qinsoon committed
184
    
185 186 187
    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;
188
    
qinsoon's avatar
qinsoon committed
189
    fn emit_ret(&mut self);
qinsoon's avatar
qinsoon committed
190

191
    fn emit_push_r64(&mut self, src: &P<Value>);
192
    fn emit_push_imm32(&mut self, src: i32);
193
    fn emit_pop_r64(&mut self, dest: &P<Value>);
194 195 196 197 198

    // 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
199

200 201 202 203
    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
204 205 206 207
    // fp add
    fn emit_addsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem);

208 209 210
    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
211 212 213 214
    // fp sub
    fn emit_subsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_subsd_f64_mem64(&mut self, dest: Reg, src: Mem);

215 216 217
    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
218 219 220 221
    // fp div
    fn emit_divsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_divsd_f64_mem64(&mut self, dest: Reg, src: Mem);

222 223 224
    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
225 226 227 228
    // fp mul
    fn emit_mulsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_mulsd_f64_mem64(&mut self, dest: Reg, src: Mem);

229 230 231
    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
232 233 234
    // 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
235

236 237 238
    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
239 240 241
    // fp conversion
    fn emit_cvtsi2sd_f64_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cvtsd2si_r_f64  (&mut self, dest: Reg, src: Reg);
242 243 244

    fn emit_cvtsi2ss_f32_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cvtss2si_r_f32  (&mut self, dest: Reg, src: Reg);
245 246 247

    // used for unsigned int to fp conversion

248
    fn emit_cvttsd2si_r_f64 (&mut self, dest: Reg, src: Reg);
qinsoon's avatar
qinsoon committed
249
    fn emit_cvttss2si_r_f32 (&mut self, dest: Reg, src: Reg);
250

251 252 253 254 255 256
    // 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);
257 258 259 260

    // 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
261 262

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