codegen.rs 7.51 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;
6
use compiler::backend::{Reg, Mem};
7

8
pub trait CodeGenerator {
qinsoon's avatar
qinsoon committed
9
    fn start_code(&mut self, func_name: 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 24 25

    fn emit_frame_grow(&mut self);
    fn emit_frame_shrink(&mut self);
26
    
27
    fn emit_nop(&mut self, bytes: usize);
28 29

    // comparison
30 31 32
    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);
33 34

    // gpr move
qinsoon's avatar
qinsoon committed
35 36

    // mov imm64 to r64
37
    fn emit_mov_r64_imm64  (&mut self, dest: Reg, src: i64);
qinsoon's avatar
qinsoon committed
38 39
    // mov r64 to fpr
    fn emit_mov_fpr_r64 (&mut self, dest: Reg, src: Reg);
40 41 42 43 44 45 46 47 48 49

    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
    fn emit_mov_mem_imm(&mut self, dest: Mem, src: i32); // store

    // 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);
50

qinsoon's avatar
qinsoon committed
51 52 53 54 55 56
    // 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);

qinsoon's avatar
qinsoon committed
57 58
    // gpr conditional move

59 60
    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
61

62 63
    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
64

65 66
    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
67

68 69
    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
70

71 72
    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
73

74 75
    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
76

77 78
    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
79

80 81
    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
82

83 84
    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
85

86 87
    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
88

89
    // lea
90
    fn emit_lea_r64(&mut self, dest: Reg, src: Mem);
91 92

    // and
93 94 95
    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);
96

97 98 99 100
    // 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);
101

102
    // xor
103 104 105
    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);
106

107
    // add
108 109 110
    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
111
    
112
    // sub
113 114 115
    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);
116 117

    // multiply
118 119
    fn emit_mul_r  (&mut self, src: Reg);
    fn emit_mul_mem(&mut self, src: Mem);
120 121

    // div
122 123
    fn emit_div_r   (&mut self, src: Reg);
    fn emit_div_mem (&mut self, src: Mem);
124 125

    // idiv
126 127
    fn emit_idiv_r  (&mut self, src: Reg);
    fn emit_idiv_mem(&mut self, src: Mem);
128 129

    // shl
130 131 132 133 134 135 136 137
    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
138

qinsoon's avatar
qinsoon committed
139 140 141
    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
142
    
143 144 145 146 147 148 149 150 151 152 153
    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
154
    
qinsoon's avatar
qinsoon committed
155 156 157
    fn emit_call_near_rel32(&mut self, callsite: String, func: MuName) -> ValueLocation;
    fn emit_call_near_r64(&mut self, callsite: String, func: &P<Value>) -> ValueLocation;
    fn emit_call_near_mem64(&mut self, callsite: String, func: &P<Value>) -> ValueLocation;
158
    
qinsoon's avatar
qinsoon committed
159
    fn emit_ret(&mut self);
qinsoon's avatar
qinsoon committed
160

161
    fn emit_push_r64(&mut self, src: &P<Value>);
162
    fn emit_push_imm32(&mut self, src: i32);
163
    fn emit_pop_r64(&mut self, dest: &P<Value>);
164 165 166 167 168

    // 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
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

    // 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);
189 190 191 192

    // fp conversion
    fn emit_cvtsi2sd_f64_r  (&mut self, dest: Reg, src: Reg);
    fn emit_cvtsd2si_r_f64  (&mut self, dest: Reg, src: Reg);
193
    fn emit_cvttsd2si_r_f64 (&mut self, dest: Reg, src: Reg);
194 195 196 197 198 199 200 201 202

    // 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);
203 204 205 206

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