codegen.rs 7.66 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

7 8 9
pub type Reg<'a> = &'a P<Value>;
pub type Mem<'a> = &'a P<Value>;

10
pub trait CodeGenerator {
qinsoon's avatar
qinsoon committed
11
    fn start_code(&mut self, func_name: MuName) -> ValueLocation;
12
    fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode + Sync + Send>, ValueLocation);
13 14 15 16

    // generate unnamed sequence of linear code (no branch)
    fn start_code_sequence(&mut self);
    fn finish_code_sequence(&mut self) -> Box<MachineCode + Sync + Send>;
17 18 19
    
    fn print_cur_code(&self);
    
qinsoon's avatar
qinsoon committed
20
    fn start_block(&mut self, block_name: MuName);
qinsoon's avatar
qinsoon committed
21
    fn start_exception_block(&mut self, block_name: MuName) -> ValueLocation;
qinsoon's avatar
qinsoon committed
22 23 24
    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);
25
    
26
    fn emit_nop(&mut self, bytes: usize);
27 28

    // comparison
29 30 31
    fn emit_cmp_r64_r64  (&mut self, op1: Reg, op2: Reg);
    fn emit_cmp_r64_imm32(&mut self, op1: Reg, op2: i32);
    fn emit_cmp_r64_mem64(&mut self, op1: Reg, op2: Mem);
32

33 34 35
    fn emit_cmp_r32_r32  (&mut self, op1: Reg, op2: Reg);
    fn emit_cmp_r32_imm32(&mut self, op1: Reg, op2: i32);
    fn emit_cmp_r32_mem32(&mut self, op1: Reg, op2: Mem);
36

37 38 39
    fn emit_cmp_r16_r16  (&mut self, op1: Reg, op2: Reg);
    fn emit_cmp_r16_imm16(&mut self, op1: Reg, op2: i16);
    fn emit_cmp_r16_mem16(&mut self, op1: Reg, op2: Mem);
40

41 42 43
    fn emit_cmp_r8_r8    (&mut self, op1: Reg, op2: Reg);
    fn emit_cmp_r8_imm8  (&mut self, op1: Reg, op2: i8);
    fn emit_cmp_r8_mem8  (&mut self, op1: Reg, op2: Mem);
44 45

    // gpr move
46
    
47 48 49 50 51 52 53 54 55 56 57
    fn emit_mov_r64_imm32  (&mut self, dest: Reg, src: i32);
    fn emit_mov_r64_mem64  (&mut self, dest: Reg, src: Mem); // load
    fn emit_mov_r64_r64    (&mut self, dest: Reg, src: Reg);
    fn emit_mov_mem64_r64  (&mut self, dest: Mem, src: Reg); // store
    fn emit_mov_mem64_imm32(&mut self, dest: Mem, src: i32);

    fn emit_mov_r32_imm32  (&mut self, dest: Reg, src: i32);
    fn emit_mov_r32_mem32  (&mut self, dest: Reg, src: Mem); // load
    fn emit_mov_r32_r32    (&mut self, dest: Reg, src: Reg);
    fn emit_mov_mem32_r32  (&mut self, dest: Mem, src: Reg); // store
    fn emit_mov_mem32_imm32(&mut self, dest: Mem, src: i32);
qinsoon's avatar
qinsoon committed
58
    
59 60 61 62 63 64 65 66 67 68 69
    fn emit_mov_r16_imm16  (&mut self, dest: Reg, src: i16);
    fn emit_mov_r16_mem16  (&mut self, dest: Reg, src: Mem); // load
    fn emit_mov_r16_r16    (&mut self, dest: Reg, src: Reg);
    fn emit_mov_mem16_r16  (&mut self, dest: Mem, src: Reg); // store
    fn emit_mov_mem16_imm16(&mut self, dest: Mem, src: i16);

    fn emit_mov_r8_imm8    (&mut self, dest: Reg, src: i8);
    fn emit_mov_r8_mem8    (&mut self, dest: Reg, src: Mem); // load
    fn emit_mov_r8_r8      (&mut self, dest: Reg, src: Mem);
    fn emit_mov_mem8_r8    (&mut self, dest: Mem, src: Reg); // store
    fn emit_mov_mem8_imm8  (&mut self, dest: Mem, src: i8);
70 71

    // lea
72
    fn emit_lea_r64(&mut self, dest: Reg, src: Reg);
73 74

    // and
75 76 77
    fn emit_and_r64_imm32(&mut self, dest: Reg, src: i32);
    fn emit_and_r64_r64  (&mut self, dest: Reg, src: Reg);
    fn emit_and_r64_mem64(&mut self, dest: Reg, src: Mem);
78

79 80 81
    fn emit_and_r32_imm32(&mut self, dest: Reg, src: i32);
    fn emit_and_r32_r32  (&mut self, dest: Reg, src: Reg);
    fn emit_and_r32_mem32(&mut self, dest: Reg, src: Mem);
82

83 84 85
    fn emit_and_r16_imm16(&mut self, dest: Reg, src: i16);
    fn emit_and_r16_r16  (&mut self, dest: Reg, src: Reg);
    fn emit_and_r16_mem16(&mut self, dest: Reg, src: Mem);
86

87 88 89
    fn emit_and_r8_imm8  (&mut self, dest: Reg, src: i8);
    fn emit_and_r8_r8    (&mut self, dest: Reg, src: Reg);
    fn emit_and_r8_mem8  (&mut self, dest: Reg, src: Mem);
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 119 120 121 122 123
    // xor
    fn emit_xor_r64_r64  (&mut self, dest: Reg, src: Reg);
    fn emit_xor_r64_mem64(&mut self, dest: Reg, src: Mem);
    fn emit_xor_r64_imm32(&mut self, dest: Reg, src: i32);

    fn emit_xor_r32_r32  (&mut self, dest: Reg, src: Reg);
    fn emit_xor_r32_mem32(&mut self, dest: Reg, src: Mem);
    fn emit_xor_r32_imm32(&mut self, dest: Reg, src: i32);

    fn emit_xor_r16_r16  (&mut self, dest: Reg, src: Reg);
    fn emit_xor_r16_mem16(&mut self, dest: Reg, src: Reg);
    fn emit_xor_r16_imm16(&mut self, dest: Reg, src: i16);

    fn emit_xor_r8_r8    (&mut self, dest: Reg, src: Reg);
    fn emit_xor_r8_mem8  (&mut self, dest: Reg, src: Reg);
    fn emit_xor_r8_imm8  (&mut self, dest: Reg, src: i8);

    // and
    fn emit_add_r64_r64  (&mut self, dest: Reg, src: Reg);
    fn emit_add_r64_mem64(&mut self, dest: Reg, src: Mem);
    fn emit_add_r64_imm32(&mut self, dest: Reg, src: i32);
//
//    fn emit_add_r32_r32  (&mut self, dest: Reg, src: Reg);
//    fn emit_add_r32_mem32(&mut self, dest: Reg, src: Mem);
//    fn emit_add_r32_imm32(&mut self, dest: Reg, src: i32);
//
//    fn emit_add_r16_r16  (&mut self, dest: Reg, src: Reg);
//    fn emit_add_r16_mem16(&mut self, dest: Reg, src: Mem);
//    fn emit_add_r16_imm16(&mut self, dest: Reg, src: i16);
//
//    fn emit_add_r8_r8  (&mut self, dest: Reg, src: Reg);
//    fn emit_add_r8_mem8(&mut self, dest: Reg, src: Mem);
//    fn emit_add_r8_imm8(&mut self, dest: Reg, src: i8);
qinsoon's avatar
qinsoon committed
124 125 126

    fn emit_addsd_f64_f64  (&mut self, dest: &P<Value>, src: &P<Value>);
    fn emit_addsd_f64_mem64(&mut self, dest: &P<Value>, src: &P<Value>);
qinsoon's avatar
qinsoon committed
127 128 129
    
    fn emit_sub_r64_r64(&mut self, dest: &P<Value>, src: &P<Value>);
    fn emit_sub_r64_mem64(&mut self, dest: &P<Value>, src: &P<Value>);
130
    fn emit_sub_r64_imm32(&mut self, dest: &P<Value>, src: i32);
qinsoon's avatar
qinsoon committed
131
    
qinsoon's avatar
qinsoon committed
132
    fn emit_mul_r64  (&mut self, src: &P<Value>);
133
    fn emit_mul_mem64(&mut self, src: &P<Value>);
134

qinsoon's avatar
sdiv  
qinsoon committed
135 136 137 138 139
    fn emit_div_r64   (&mut self, src: &P<Value>);
    fn emit_div_mem64 (&mut self, src: &P<Value>);
    fn emit_idiv_r64  (&mut self, src: &P<Value>);
    fn emit_idiv_mem64(&mut self, src: &P<Value>);

140 141 142 143
    fn emit_shl_r64_cl    (&mut self, dest: &P<Value>);
    fn emit_shl_mem64_cl  (&mut self, dest: &P<Value>);
    fn emit_shl_r64_imm8  (&mut self, dest: &P<Value>, src: i8);
    fn emit_shl_mem64_imm8(&mut self, dest: &P<Value>, src: i8);
qinsoon's avatar
shl  
qinsoon committed
144

qinsoon's avatar
qinsoon committed
145 146 147 148 149 150 151 152 153 154
    fn emit_shr_r64_cl    (&mut self, dest: &P<Value>);
    fn emit_shr_mem64_cl  (&mut self, dest: &P<Value>);
    fn emit_shr_r64_imm8  (&mut self, dest: &P<Value>, src: i8);
    fn emit_shr_mem64_imm8(&mut self, dest: &P<Value>, src: i8);

    fn emit_sar_r64_cl    (&mut self, dest: &P<Value>);
    fn emit_sar_mem64_cl  (&mut self, dest: &P<Value>);
    fn emit_sar_r64_imm8  (&mut self, dest: &P<Value>, src: i8);
    fn emit_sar_mem64_imm8(&mut self, dest: &P<Value>, src: i8);

qinsoon's avatar
sdiv  
qinsoon committed
155
    fn emit_cqo(&mut self);
156
    
157 158 159 160 161 162 163 164 165 166 167
    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
168
    
qinsoon's avatar
qinsoon committed
169 170 171
    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;
172
    
qinsoon's avatar
qinsoon committed
173
    fn emit_ret(&mut self);
qinsoon's avatar
qinsoon committed
174

175
    fn emit_push_r64(&mut self, src: &P<Value>);
176
    fn emit_push_imm32(&mut self, src: i32);
177
    fn emit_pop_r64(&mut self, dest: &P<Value>);
178 179 180 181 182 183

    // 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
184
}