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 8.63 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 42

    // gpr move
qinsoon's avatar
qinsoon committed
43 44

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

    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
53 54 55
    // 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
56

57 58 59 60
    fn emit_mov_mem_r_callee_saved  (&mut self, dest: Mem, src: Reg); // store callee saved register
    fn emit_mov_r_mem_callee_saved  (&mut self, dest: Reg, src: Mem); // load callee saved register


qinsoon's avatar
qinsoon committed
61 62 63
    // 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);
64

qinsoon's avatar
qinsoon committed
65 66 67 68 69 70
    // 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);

71 72 73 74 75 76 77 78 79 80 81
    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
82 83
    // gpr conditional move

qinsoon's avatar
qinsoon committed
84 85
    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
86

qinsoon's avatar
qinsoon committed
87 88
    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
89

qinsoon's avatar
qinsoon committed
90 91
    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
92

qinsoon's avatar
qinsoon committed
93 94
    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
95

qinsoon's avatar
qinsoon committed
96 97
    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
98

qinsoon's avatar
qinsoon committed
99 100
    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
101

qinsoon's avatar
qinsoon committed
102 103
    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
104

qinsoon's avatar
qinsoon committed
105 106
    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
107

qinsoon's avatar
qinsoon committed
108 109
    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
110

qinsoon's avatar
qinsoon committed
111 112
    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
113

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

    // and
qinsoon's avatar
qinsoon committed
118 119 120
    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);
121

qinsoon's avatar
qinsoon committed
122 123 124 125
    // 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);
126

127
    // xor
qinsoon's avatar
qinsoon committed
128 129 130
    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);
131

132
    // add
qinsoon's avatar
qinsoon committed
133 134 135
    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
136
    
137
    // sub
qinsoon's avatar
qinsoon committed
138 139 140
    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);
141 142

    // multiply
qinsoon's avatar
qinsoon committed
143 144
    fn emit_mul_r  (&mut self, src: Reg);
    fn emit_mul_mem(&mut self, src: Mem);
145 146

    // div
qinsoon's avatar
qinsoon committed
147 148
    fn emit_div_r   (&mut self, src: Reg);
    fn emit_div_mem (&mut self, src: Mem);
149 150

    // idiv
qinsoon's avatar
qinsoon committed
151 152
    fn emit_idiv_r  (&mut self, src: Reg);
    fn emit_idiv_mem(&mut self, src: Mem);
153 154

    // shl
qinsoon's avatar
qinsoon committed
155 156 157 158 159 160 161 162
    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
163

qinsoon's avatar
qinsoon committed
164 165 166
    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
167
    
168 169 170 171 172 173 174 175 176 177 178
    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
179
    
180 181 182
    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;
183
    
qinsoon's avatar
qinsoon committed
184
    fn emit_ret(&mut self);
qinsoon's avatar
qinsoon committed
185

186
    fn emit_push_r64(&mut self, src: &P<Value>);
187
    fn emit_push_imm32(&mut self, src: i32);
188
    fn emit_pop_r64(&mut self, dest: &P<Value>);
189 190 191 192 193

    // 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
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213

    // fp add
    fn emit_addsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_addsd_f64_mem64(&mut self, dest: Reg, src: Mem);

    // fp sub
    fn emit_subsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_subsd_f64_mem64(&mut self, dest: Reg, src: Mem);

    // fp div
    fn emit_divsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_divsd_f64_mem64(&mut self, dest: Reg, src: Mem);

    // fp mul
    fn emit_mulsd_f64_f64  (&mut self, dest: Reg, src: Reg);
    fn emit_mulsd_f64_mem64(&mut self, dest: Reg, src: Mem);

    // 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
214 215 216 217

    // fp conversion
    fn emit_cvtsi2sd_f64_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cvtsd2si_r_f64  (&mut self, dest: Reg, src: Reg);
218
    fn emit_cvttsd2si_r_f64 (&mut self, dest: Reg, src: Reg);
219 220 221 222 223 224 225 226 227

    // used for unsigned int to fp conversion

    // 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);
228 229 230 231

    // 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);
232
}