WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

codegen.rs 9.57 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>;
qinsoon's avatar
qinsoon committed
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);
qinsoon's avatar
qinsoon committed
25
    
qinsoon's avatar
qinsoon committed
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);
qinsoon's avatar
qinsoon committed
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    // 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);

108
    // add
109
110
111
    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);
112
113
114
115
116
117
118
119
120
121
122
123

    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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    // sub
    fn emit_sub_r64_r64  (&mut self, dest: Reg, src: Reg);
    fn emit_sub_r64_mem64(&mut self, dest: Reg, src: Mem);
    fn emit_sub_r64_imm32(&mut self, dest: Reg, src: i32);

    fn emit_sub_r32_r32  (&mut self, dest: Reg, src: Reg);
    fn emit_sub_r32_mem32(&mut self, dest: Reg, src: Mem);
    fn emit_sub_r32_imm32(&mut self, dest: Reg, src: i32);

    fn emit_sub_r16_r16  (&mut self, dest: Reg, src: Reg);
    fn emit_sub_r16_mem16(&mut self, dest: Reg, src: Mem);
    fn emit_sub_r16_imm16(&mut self, dest: Reg, src: i16);

    fn emit_sub_r8_r8  (&mut self, dest: Reg, src: Reg);
    fn emit_sub_r8_mem8(&mut self, dest: Reg, src: Mem);
    fn emit_sub_r8_imm8(&mut self, dest: Reg, src: i8);

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

    // multiply
    fn emit_mul_r64  (&mut self, src: Reg);
    fn emit_mul_r32  (&mut self, src: Reg);
    fn emit_mul_r16  (&mut self, src: Reg);
    fn emit_mul_r8   (&mut self, src: Reg);

    fn emit_mul_mem64(&mut self, src: Mem);
    fn emit_mul_mem32(&mut self, src: Mem);
    fn emit_mul_mem16(&mut self, src: Mem);
    fn emit_mul_mem8 (&mut self, src: Mem);

    // div
    fn emit_div_r64   (&mut self, src: Reg);
    fn emit_div_r32   (&mut self, src: Reg);
    fn emit_div_r16   (&mut self, src: Reg);
    fn emit_div_r8    (&mut self, src: Reg);

    fn emit_div_mem64 (&mut self, src: Mem);
    fn emit_div_mem32 (&mut self, src: Mem);
    fn emit_div_mem16 (&mut self, src: Mem);
    fn emit_div_mem8  (&mut self, src: Mem);

    // idiv
    fn emit_idiv_r64  (&mut self, src: Reg);
    fn emit_idiv_r32  (&mut self, src: Reg);
    fn emit_idiv_r16  (&mut self, src: Reg);
    fn emit_idiv_r8   (&mut self, src: Reg);

    fn emit_idiv_mem64(&mut self, src: Mem);
    fn emit_idiv_mem32(&mut self, src: Mem);
    fn emit_idiv_mem16(&mut self, src: Mem);
    fn emit_idiv_mem8 (&mut self, src: Mem);

    // shl
    fn emit_shl_r64_cl    (&mut self, dest: Reg);
//    fn emit_shl_r32_cl    (&mut self, dest: Reg);
//    fn emit_shl_r16_cl    (&mut self, dest: Reg);
//    fn emit_shl_r8_cl     (&mut self, dest: Reg);

    fn emit_shl_mem64_cl  (&mut self, dest: Mem);
//    fn emit_shl_mem32_cl  (&mut self, dest: Mem);
//    fn emit_shl_mem16_cl  (&mut self, dest: Mem);
//    fn emit_shl_mem8_cl   (&mut self, dest: Mem);

    fn emit_shl_r64_imm8  (&mut self, dest: Reg, src: i8);
//    fn emit_shl_r32_imm8  (&mut self, dest: Reg, src: i8);
//    fn emit_shl_r16_imm8  (&mut self, dest: Reg, src: i8);
//    fn emit_shl_r8_imm8   (&mut self, dest: Reg, src: i8);

    fn emit_shl_mem64_imm8(&mut self, dest: Mem, src: i8);
//    fn emit_shl_mem32_imm8(&mut self, dest: Mem, src: i8);
//    fn emit_shl_mem16_imm8(&mut self, dest: Mem, src: i8);
//    fn emit_shl_mem8_imm8 (&mut self, dest: Mem, src: i8);
qinsoon's avatar
shl    
qinsoon committed
199

qinsoon's avatar
qinsoon committed
200
201
202
203
204
205
206
207
208
209
    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
210
    fn emit_cqo(&mut self);
211
    
212
213
214
215
216
217
218
219
220
221
222
    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
223
    
qinsoon's avatar
qinsoon committed
224
225
226
    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;
227
    
qinsoon's avatar
qinsoon committed
228
    fn emit_ret(&mut self);
qinsoon's avatar
qinsoon committed
229

qinsoon's avatar
qinsoon committed
230
    fn emit_push_r64(&mut self, src: &P<Value>);
231
    fn emit_push_imm32(&mut self, src: i32);
qinsoon's avatar
qinsoon committed
232
    fn emit_pop_r64(&mut self, dest: &P<Value>);
233
234
235
236
237
238

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