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