More fixes for code generation (CONV_I1/CONV_I2)
[mono.git] / mono / mini / inssel-s390.brg
blobcbd317134177c003dd9790d72056643e1614a0e4
1 %%
4 # inssel-s390.brg: burg file for special s390 instructions
6 # Author:
7 #   Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
8 #   Dietmar Maurer (dietmar@ximian.com)
9 #   Paolo Molaro (lupus@ximian.com)
11 # (C) 2002 Ximian, Inc.
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);
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);
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);
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);
39 freg: OP_LCONV_TO_R8 (lreg) {
40         mono_bblock_add_inst (s->cbb, tree);
43 freg: OP_LCONV_TO_R4 (lreg) {
44         mono_bblock_add_inst (s->cbb, tree);
47 freg: CEE_CONV_R_UN (reg) {
48         mono_bblock_add_inst (s->cbb, tree);
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);
59 reg: OP_LOCALLOC (reg) {
60         tree->dreg = state->reg1;
61         tree->sreg1 = state->left->reg1;
62         mono_bblock_add_inst (s->cbb, tree);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
183 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
184         MonoInst *vt  = state->left->left->tree;
185         int start_reg = tree->sreg1;
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->inst_imm,
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->sreg2);
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         }
214 stmt: OP_OUTARG_VT (OP_ICONST) {
215         int start_reg = tree->sreg1;
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         }
232 stmt: OP_OUTARG_VT (reg) {
233         int start_reg = tree->sreg1;
234         int size      = tree->unused;
235         int nregs     = size / 4;
236         int soffset   = tree->inst_offset;
237         int i;
239         if (size < 0) { 
240                 size = -size;
241                 mini_emit_memcpy (s, s->frame_reg, tree->inst_imm,
242                                   tree->inst_basereg, soffset, size, 0);
243                 if (start_reg != STK_BASE) {
244                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
245                                                  s->frame_reg, tree->sreg2);
246                 }
247         } else {
248                 if (start_reg != STK_BASE) {
249                         for (i = 0; i < nregs; ++i) {
250                                 MONO_EMIT_NEW_LOAD_MEMBASE(s, start_reg + i, 
251                                                            s->frame_reg, 
252                                                            soffset);
253                                 soffset += sizeof(gpointer);
254                         }
255                 } else {
256                         int tmpr;
257                         tmpr = mono_regstate_next_int (s->rs);
258                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
259                                                 s->stack_offset);
260                         mini_emit_memcpy (s, s->frame_reg, soffset, tmpr, 
261                                           tree->sreg2, size, 0);
262                 }
263         }
266 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
267         /* nothing to do: the value is already on the FP stack */
270 stmt: CEE_BNE_UN (fpcflags) {
271         tree->opcode = OP_FBNE_UN;
272         mono_bblock_add_inst (s->cbb, tree);
275 stmt: CEE_BEQ (fpcflags) {
276         tree->opcode = OP_FBEQ;
277         mono_bblock_add_inst (s->cbb, tree);
280 stmt: CEE_BLT (fpcflags) {
281         tree->opcode = OP_FBLT;
282         mono_bblock_add_inst (s->cbb, tree);
285 stmt: CEE_BLT_UN (fpcflags) {
286         tree->opcode = OP_FBLT_UN;
287         mono_bblock_add_inst (s->cbb, tree);
290 stmt: CEE_BGT (fpcflags) {
291         tree->opcode = OP_FBGT;
292         mono_bblock_add_inst (s->cbb, tree);
295 stmt: CEE_BGT_UN (fpcflags) {
296         tree->opcode = OP_FBGT_UN;
297         mono_bblock_add_inst (s->cbb, tree);
300 stmt: CEE_BGE  (fpcflags) {
301         tree->opcode = OP_FBGE;
302         mono_bblock_add_inst (s->cbb, tree);
305 stmt: CEE_BGE_UN (fpcflags) {
306         tree->opcode = OP_FBGE_UN;
307         mono_bblock_add_inst (s->cbb, tree);
310 stmt: CEE_BLE  (fpcflags) {
311         tree->opcode = OP_FBLE;
312         mono_bblock_add_inst (s->cbb, tree);
315 stmt: CEE_BLE_UN (fpcflags) {
316         tree->opcode = OP_FBLE_UN;
317         mono_bblock_add_inst (s->cbb, tree);
320 stmt: CEE_POP (freg) "0" {
321         /* nothing to do */
322 }     
324 freg: OP_LCONV_TO_R8 (lreg) {
325         /* nothing to do - emulated */
328 freg: OP_LCONV_TO_R4 (lreg) {
329         /* nothing to do - emulated */
332 freg: OP_LCONV_TO_R_UN (lreg) {
333         /* nothing to do - emulated */
336 freg: OP_FREM (freg, freg) {
337         /* nothing to do - emulated */
340 reg: OP_CEQ (OP_COMPARE (freg, freg)) { 
341         MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
342                          state->left->right->reg1);
345 reg: OP_CLT (OP_COMPARE (freg, freg)) { 
346         MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
347                          state->left->right->reg1);
350 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {      
351         MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
352                          state->left->right->reg1);
355 reg: OP_CGT (OP_COMPARE (freg, freg)) { 
356         MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
357                          state->left->right->reg1);
360 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {      
361         MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
362                          state->left->right->reg1);
365 base: OP_REGOFFSET "0" {
368 base: OP_S390_STKARG "0" {
369         int tmpr;
370         tmpr = mono_regstate_next_int (s->rs);
371         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
372                                 (s->stack_offset+state->tree->unused));
373         tree->inst_offset  = state->tree->inst_offset;
374         tree->inst_basereg = tmpr;
377 base: OP_LDADDR (OP_S390_LOADARG) "0" {
378         int tmpr;
379         tmpr = mono_regstate_next_int (s->rs);
380         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 
381                                     state->left->tree->inst_offset);
382         tree->inst_offset  = 0;
383         tree->inst_basereg = tmpr;
386 base: OP_LDADDR (OP_S390_ARGPTR) "0" {
387         int tmpr;
388         tmpr = mono_regstate_next_int (s->rs);
389         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
390                                  state->left->tree->inst_offset);
391         tree->inst_offset  = 0;
392         tree->inst_basereg = tmpr;
395 base: OP_LDADDR (OP_S390_STKARG) "0" {
396         int tmpr;
397         tmpr = mono_regstate_next_int (s->rs);
398         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
399                                  (s->stack_offset + state->left->tree->unused));
400         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, tmpr, 
401                                  state->left->tree->inst_offset);
402         tree->inst_offset  = 0;
403         tree->inst_basereg = tmpr;
406 reg: OP_LDADDR (OP_S390_LOADARG) "2" {
407         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
408                                  state->left->tree->inst_offset);
409         tree->inst_offset  = 0;
410         tree->inst_basereg = state->reg1;
413 reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
414         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
415                                  state->left->tree->inst_offset);
416         tree->inst_offset  = 0;
417         tree->inst_basereg = state->reg1;
420 reg: OP_LDADDR (OP_S390_STKARG) "2" {
421         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
422                                  (s->stack_offset + state->left->tree->unused));
423         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1, 
424                                  state->left->tree->inst_offset);
425         tree->inst_offset  = 0;
426         tree->inst_basereg = state->reg1;
429 reg: CEE_LDOBJ (OP_S390_LOADARG) "1" {
430         int tmpr;
431         tmpr = mono_regstate_next_int (s->rs);
432         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 
433                                     state->left->tree->inst_offset);
434         tree->inst_offset  = 0;
435         tree->inst_basereg = tmpr;
438 reg: CEE_LDOBJ (OP_S390_ARGPTR) "1" {
439         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
440                                  state->left->tree->inst_offset);
441         tree->inst_offset  = 0;
442         tree->inst_basereg = state->reg1;
445 reg: CEE_LDOBJ (OP_S390_STKARG) "1" {
446         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
447                                  (s->stack_offset + state->left->tree->unused));
448         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
449                                  state->left->tree->inst_offset);
450         tree->inst_offset  = 0;
451         tree->inst_basereg = state->reg1;
454 base: CEE_LDOBJ (OP_S390_ARGPTR) "0" {
455         int tmpr;
456         tmpr = mono_regstate_next_int (s->rs);
457         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 
458                                     state->left->tree->inst_offset);
459         tree->inst_offset  = 0;
460         tree->inst_basereg = tmpr;
463 base: CEE_LDOBJ (OP_S390_STKARG) "0" {
464         int tmpr;
465         tmpr = mono_regstate_next_int (s->rs);
466         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
467                                  (s->stack_offset + state->left->tree->unused));
468         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, tmpr, state->left->tree->inst_offset);
469         tree->inst_offset  = 0;
470         tree->inst_basereg = tmpr;