2004-01-29 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / mini / inssel-ppc.brg
1 %%
2
3 #
4 # inssel-ppc.brg: burg file for special ppc instructions
5 #
6 # Author:
7 #   Dietmar Maurer (dietmar@ximian.com)
8 #   Paolo Molaro (lupus@ximian.com)
9 #
10 # (C) 2002 Ximian, Inc.
11 #
12
13 stmt: OP_START_HANDLER {
14         MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
15         /*MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, spvar->inst_basereg, spvar->inst_offset, ppc_sp);
16         */
17         tree->inst_left = spvar;
18         mono_bblock_add_inst (s->cbb, tree);
19 }
20
21 stmt: CEE_ENDFINALLY {
22         MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
23         tree->inst_left = spvar;
24         mono_bblock_add_inst (s->cbb, tree);
25 }
26
27 stmt: OP_ENDFILTER (reg) {
28         MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
29         tree->inst_left = spvar;
30         tree->sreg1 = state->left->reg1;
31         mono_bblock_add_inst (s->cbb, tree);
32 }
33
34 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
35         /* this should only happen for methods returning a long */
36         MONO_EMIT_NEW_UNALU (s, OP_MOVE, ppc_r3, state->right->reg1);
37         MONO_EMIT_NEW_UNALU (s, OP_MOVE, ppc_r4, state->right->reg2);
38 }
39
40 lreg: OP_LNEG (lreg) "2" {
41         MONO_EMIT_NEW_BIALU_IMM (s, OP_PPC_SUBFIC, state->reg1, state->left->reg1, 0);
42         MONO_EMIT_UNALU (s, tree, OP_PPC_SUBFZE, state->reg2, state->left->reg2);
43 }
44
45 freg: OP_LCONV_TO_R8 (lreg) {
46         mono_bblock_add_inst (s->cbb, tree);
47 }
48
49 freg: OP_LCONV_TO_R4 (lreg) {
50         mono_bblock_add_inst (s->cbb, tree);
51 }
52
53 freg: CEE_CONV_R_UN (reg) {
54         mono_bblock_add_inst (s->cbb, tree);
55 }
56
57 reg: OP_LOCALLOC (OP_ICONST) {
58         /* microcoded in mini-ppc.c */
59         tree->sreg1 = mono_regstate_next_int (s->rs);
60         MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
61         mono_bblock_add_inst (s->cbb, tree);
62 }
63
64 reg: OP_LOCALLOC (reg) {
65         mono_bblock_add_inst (s->cbb, tree);
66 }
67
68 stmt: OP_SETRET (reg) {
69         tree->opcode = OP_MOVE;
70         tree->sreg1 = state->left->reg1;
71         tree->dreg = ppc_r3;
72         mono_bblock_add_inst (s->cbb, tree);
73 }
74
75 stmt: OP_SETRET (lreg) {
76         tree->opcode = OP_SETLRET;
77         tree->sreg1 = state->left->reg1;
78         tree->sreg2 = state->left->reg2;
79         mono_bblock_add_inst (s->cbb, tree);
80 }
81
82 stmt: OP_SETRET (freg) {
83         tree->opcode = OP_FMOVE;
84         tree->sreg1 = state->left->reg1;
85         tree->dreg = ppc_f1;
86         mono_bblock_add_inst (s->cbb, tree);
87 }
88
89 stmt: OP_SETRET (OP_ICONST) {
90         tree->opcode = OP_ICONST;
91         tree->inst_c0 = state->left->tree->inst_c0;
92         tree->dreg = ppc_r3;
93         mono_bblock_add_inst (s->cbb, tree);
94 }
95
96 stmt: OP_OUTARG (reg) {
97         if (tree->inst_imm) {
98                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
99                 return;
100         }
101         tree->opcode = OP_SETREG;
102         tree->dreg = tree->unused;
103         tree->sreg1 = state->left->reg1;
104         mono_bblock_add_inst (s->cbb, tree);
105 }
106
107 stmt: OP_OUTARG (OP_REGVAR) {
108         if (tree->inst_imm) {
109                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->tree->dreg);
110                 return;
111         }
112         tree->opcode = OP_SETREG;
113         tree->dreg = tree->unused;
114         tree->sreg1 = state->left->tree->dreg;
115         mono_bblock_add_inst (s->cbb, tree);
116 }
117
118 stmt: OP_OUTARG (lreg) {
119         if (tree->inst_imm) {
120                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg2);
121                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm + 4, state->left->reg1);
122                 return;
123         }
124         MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
125         tree->opcode = OP_SETREG;
126         tree->dreg = tree->unused + 1;
127         tree->sreg1 = state->left->reg1;
128         mono_bblock_add_inst (s->cbb, tree);
129 }
130
131 stmt: OP_OUTARG (OP_ICONST) {
132         if (tree->inst_imm) {
133                 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, s->frame_reg, tree->inst_imm, state->left->tree->inst_c0);
134                 return;
135         }
136         tree->opcode = OP_SETREGIMM;
137         tree->dreg = tree->unused;
138         tree->inst_c0 = state->left->tree->inst_c0;
139         mono_bblock_add_inst (s->cbb, tree);
140 }
141
142 #stmt: OP_OUTARG (CEE_LDIND_I4 (base)) {
143 #       tree->opcode = OP_X86_PUSH_MEMBASE;
144 #       tree->inst_basereg = state->left->left->tree->inst_basereg;
145 #       tree->inst_offset = state->left->left->tree->inst_offset;
146 #       mono_bblock_add_inst (s->cbb, tree);
147 #}
148
149 #stmt: OP_OUTARG (CEE_LDIND_U4 (base)) {
150 #       tree->opcode = OP_X86_PUSH_MEMBASE;
151 #       tree->inst_basereg = state->left->left->tree->inst_basereg;
152 #       tree->inst_offset = state->left->left->tree->inst_offset;
153 #       mono_bblock_add_inst (s->cbb, tree);
154 #}
155
156 #stmt: OP_OUTARG (CEE_LDIND_I (base)) {
157 #       tree->opcode = OP_X86_PUSH_MEMBASE;
158 #       tree->inst_basereg = state->left->left->tree->inst_basereg;
159 #       tree->inst_offset = state->left->left->tree->inst_offset;
160 #       mono_bblock_add_inst (s->cbb, tree);
161 #}
162
163 #stmt: OP_OUTARG (CEE_LDIND_REF (base)) {
164 #       tree->opcode = OP_X86_PUSH_MEMBASE;
165 #       tree->inst_basereg = state->left->left->tree->inst_basereg;
166 #       tree->inst_offset = state->left->left->tree->inst_offset;
167 #       mono_bblock_add_inst (s->cbb, tree);
168 #}
169
170 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
171         if (tree->inst_imm) {
172                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->left->tree->dreg);
173                 return;
174         }
175         tree->opcode = OP_SETREG;
176         tree->sreg1 = state->left->left->tree->dreg;
177         tree->dreg = tree->unused;
178         mono_bblock_add_inst (s->cbb, tree);
179 }
180
181 #stmt: OP_OUTARG (CEE_LDOBJ (reg)) {
182 #       tree->opcode = OP_X86_PUSH;
183 #       tree->sreg1 = state->left->reg1;
184 #       mono_bblock_add_inst (s->cbb, tree);
185 #}
186
187 stmt: OP_OUTARG (freg) {
188         if (tree->inst_imm) {
189                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
190                 return;
191         }
192         tree->opcode = OP_SETFREG;
193         tree->sreg1 = state->left->reg1;
194         tree->dreg = tree->unused;
195         mono_bblock_add_inst (s->cbb, tree);
196 }
197
198 stmt: OP_OUTARG_R4 (freg) {
199         if (tree->inst_imm) {
200                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
201                 return;
202         }
203         tree->opcode = OP_SETFREG;
204         tree->sreg1 = state->left->reg1;
205         tree->dreg = tree->unused;
206         mono_bblock_add_inst (s->cbb, tree);
207 }
208
209 stmt: OP_OUTARG_R8 (freg) {
210         if (tree->inst_imm) {
211                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
212                 return;
213         }
214         tree->opcode = OP_SETFREG;
215         tree->sreg1 = state->left->reg1;
216         tree->dreg = tree->unused;
217         mono_bblock_add_inst (s->cbb, tree);
218 }
219
220 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
221         MonoInst *vt = state->left->left->tree;
222         int start_reg = tree->unused & 0xff;
223         int nregs = (tree->unused >> 8) & 0xff;
224         int ovf_size = (tree->unused >> 16) & 0xffff;
225         int i, tmpr, soffset;
226         soffset = vt->inst_offset;
227         for (i = 0; i < nregs; ++i) {
228                 tmpr = mono_regstate_next_int (s->rs);
229                 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, vt->inst_basereg, soffset);
230                 MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg + i, tmpr);
231                 soffset += sizeof (gpointer);
232         }
233         //g_print ("vt size: %d at R%d + %d\n", tree->inst_imm, vt->inst_basereg, vt->inst_offset);
234         if (ovf_size != 0) {
235                 mini_emit_memcpy (s, s->frame_reg, tree->inst_imm + (soffset - vt->inst_offset), vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
236         }
237 }
238
239 stmt: OP_OUTARG_VT (OP_ICONST) {
240         int start_reg = tree->unused & 0xff;
241         int nregs = (tree->unused >> 8) & 0xff;
242         int ovf_size = (tree->unused >> 16) & 0xffff;
243         if (nregs) {
244                 tree->opcode = OP_SETREGIMM;
245                 tree->dreg = start_reg;
246                 tree->inst_c0 = state->left->tree->inst_c0;
247                 mono_bblock_add_inst (s->cbb, tree);
248         } else {
249                 g_assert_not_reached ();
250         }
251 }
252
253 stmt: OP_OUTARG_VT (reg) {
254         int start_reg = tree->unused & 0xff;
255         int nregs = (tree->unused >> 8) & 0xff;
256         int ovf_size = (tree->unused >> 16) & 0xffff;
257         if (nregs) {
258                 tree->opcode = OP_SETREG;
259                 tree->dreg = start_reg;
260                 tree->sreg1 = state->left->tree->dreg;
261                 mono_bblock_add_inst (s->cbb, tree);
262         } else {
263                 g_assert_not_reached ();
264         }
265 }
266
267 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
268         /* nothing to do: the value is already on the FP stack */
269 }
270
271 stmt: CEE_BNE_UN (fpcflags) {
272         tree->opcode = OP_FBNE_UN;
273         mono_bblock_add_inst (s->cbb, tree);
274 }
275
276 stmt: CEE_BEQ (fpcflags) {
277         tree->opcode = OP_FBEQ;
278         mono_bblock_add_inst (s->cbb, tree);
279 }
280
281 stmt: CEE_BLT (fpcflags) {
282         tree->opcode = OP_FBLT;
283         mono_bblock_add_inst (s->cbb, tree);
284 }
285
286 stmt: CEE_BLT_UN (fpcflags) {
287         tree->opcode = OP_FBLT_UN;
288         mono_bblock_add_inst (s->cbb, tree);
289 }
290
291 stmt: CEE_BGT (fpcflags) {
292         tree->opcode = OP_FBGT;
293         mono_bblock_add_inst (s->cbb, tree);
294 }
295
296 stmt: CEE_BGT_UN (fpcflags) {
297         tree->opcode = OP_FBGT_UN;
298         mono_bblock_add_inst (s->cbb, tree);
299 }
300
301 stmt: CEE_BGE  (fpcflags) {
302         tree->opcode = OP_FBGE;
303         mono_bblock_add_inst (s->cbb, tree);
304 }
305
306 stmt: CEE_BGE_UN (fpcflags) {
307         tree->opcode = OP_FBGE_UN;
308         mono_bblock_add_inst (s->cbb, tree);
309 }
310
311 stmt: CEE_BLE  (fpcflags) {
312         tree->opcode = OP_FBLE;
313         mono_bblock_add_inst (s->cbb, tree);
314 }
315
316 stmt: CEE_BLE_UN (fpcflags) {
317         tree->opcode = OP_FBLE_UN;
318         mono_bblock_add_inst (s->cbb, tree);
319 }
320
321 stmt: CEE_POP (freg) "0" {
322         /* nothing to do */
323 }     
324
325 freg: OP_LCONV_TO_R8 (lreg) {
326         /* nothing to do - emulated */
327 }
328
329 freg: OP_LCONV_TO_R4 (lreg) {
330         /* nothing to do - emulated */
331 }
332
333 freg: OP_LCONV_TO_R_UN (lreg) {
334         /* nothing to do - emulated */
335 }
336
337 freg: OP_FREM (freg, freg) {
338         /* nothing to do - emulated */
339 }
340
341 reg: OP_CEQ (OP_COMPARE (freg, freg)) { 
342         MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
343                          state->left->right->reg1);
344 }
345
346 reg: OP_CLT (OP_COMPARE (freg, freg)) { 
347         MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
348                          state->left->right->reg1);
349 }
350
351 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {      
352         MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
353                          state->left->right->reg1);
354 }
355
356 reg: OP_CGT (OP_COMPARE (freg, freg)) { 
357         MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
358                          state->left->right->reg1);
359 }
360
361 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {      
362         MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
363                          state->left->right->reg1);
364 }
365
366 %%