4 # inssel-s390.brg: burg file for special s390 instructions
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);
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 lreg: OP_LADD (lreg, lreg),
34 lreg: OP_LADD_OVF (lreg, lreg),
35 lreg: OP_LADD_OVF_UN (lreg, lreg),
36 lreg: OP_LSUB (lreg, lreg),
37 lreg: OP_LSUB_OVF (lreg, lreg),
38 lreg: OP_LSUB_OVF_UN (lreg, lreg) "0" {
39 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r0, state->left->reg1);
40 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r1, state->left->reg2);
41 tree->dreg = state->reg1;
42 tree->sreg1 = state->right->reg1;
43 tree->sreg2 = state->right->reg2;
44 mono_bblock_add_inst (s->cbb, tree);
47 lreg: OP_LADD (lreg, i8con) "0" {
48 MONO_EMIT_NEW_ICONST (s, s390_r0, state->right->tree->inst_ls_word);
49 MONO_EMIT_NEW_ICONST (s, s390_r1, state->right->tree->inst_ms_word);
50 tree->dreg = state->reg1;
51 tree->sreg1 = state->left->reg1;
52 tree->sreg2 = state->left->reg2;
53 mono_bblock_add_inst (s->cbb, tree);
56 lreg: OP_LSUB (lreg, i8con) "0" {
59 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r0, state->left->reg1);
60 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r1, state->left->reg2);
61 rh = mono_regstate_next_int (s->rs);
62 MONO_EMIT_NEW_ICONST (s, rh, state->right->tree->inst_ls_word);
63 rl = mono_regstate_next_int (s->rs);
64 MONO_EMIT_NEW_ICONST (s, rl, state->right->tree->inst_ms_word);
65 tree->dreg = state->reg1;
68 mono_bblock_add_inst (s->cbb, tree);
71 reg: CEE_ADD_OVF (reg, reg) "0" {
72 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
75 reg: CEE_ADD_OVF_UN (reg, reg) "0" {
76 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
79 reg: CEE_SUB_OVF (reg, reg) "0" {
80 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
83 reg: CEE_SUB_OVF_UN (reg, reg) "0" {
84 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
87 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
88 /*------------------------------------------------------*/
89 /* this should only happen for methods returning a long */
90 /* S/390 ABI uses r2/r3 for returning 64-bit integers */
91 /*------------------------------------------------------*/
92 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r2, state->right->reg1);
93 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r3, state->right->reg2);
96 freg: OP_LCONV_TO_R8 (lreg) {
97 tree->dreg = state->reg1;
98 tree->sreg1 = state->left->reg1;
99 tree->sreg2 = state->left->reg2;
100 mono_bblock_add_inst (s->cbb, tree);
103 freg: OP_LCONV_TO_R4 (lreg) {
104 tree->dreg = state->reg1;
105 tree->sreg1 = state->left->reg1;
106 tree->sreg2 = state->left->reg2;
107 mono_bblock_add_inst (s->cbb, tree);
110 freg: CEE_CONV_R_UN (reg) {
111 tree->dreg = state->reg1;
112 tree->sreg1 = state->left->reg1;
113 mono_bblock_add_inst (s->cbb, tree);
116 freg: CEE_CONV_R_UN (reg) {
117 mono_bblock_add_inst (s->cbb, tree);
120 stmt: OP_MEMCPY (reg, reg) "0" {
121 int size = tree->backend.memcpy_args->size;
123 MONO_EMIT_NEW_MOVE (s, state->left->reg1, 0,
124 state->right->reg1, 0, size);
127 stmt: OP_MEMCPY (base, base) "0" {
128 int size = tree->backend.memcpy_args->size;
130 MONO_EMIT_NEW_MOVE (s, state->left->tree->sreg1,
131 state->left->tree->inst_offset,
132 state->right->tree->sreg1,
133 state->right->tree->inst_offset,
137 reg: OP_LOCALLOC (OP_ICONST) {
138 /* microcoded in mini-s390.c */
139 tree->sreg1 = mono_regstate_next_int (s->rs);
140 tree->dreg = state->reg1;
141 MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
142 mono_bblock_add_inst (s->cbb, tree);
145 reg: OP_LOCALLOC (reg) {
146 tree->dreg = state->reg1;
147 tree->sreg1 = state->left->reg1;
148 mono_bblock_add_inst (s->cbb, tree);
151 stmt: OP_SETRET (reg) {
152 tree->opcode = OP_MOVE;
153 tree->sreg1 = state->left->reg1;
154 tree->dreg = s390_r2;
155 mono_bblock_add_inst (s->cbb, tree);
158 stmt: OP_SETRET (lreg) {
159 tree->opcode = OP_SETLRET;
160 tree->sreg1 = state->left->reg1;
161 tree->sreg2 = state->left->reg2;
162 mono_bblock_add_inst (s->cbb, tree);
165 stmt: OP_SETRET (freg) {
166 if (mono_method_signature (s->method)->ret->type == MONO_TYPE_R4) {
167 tree->opcode = OP_S390_SETF4RET;
168 tree->sreg1 = state->left->reg1;
169 // tree->dreg = s390_f0;
171 tree->opcode = OP_FMOVE;
172 tree->sreg1 = state->left->reg1;
173 // tree->dreg = s390_f0;
175 mono_bblock_add_inst (s->cbb, tree);
178 stmt: OP_SETRET (OP_ICONST) {
179 tree->opcode = OP_ICONST;
180 tree->inst_c0 = state->left->tree->inst_c0;
181 tree->dreg = s390_r2;
182 mono_bblock_add_inst (s->cbb, tree);
185 stmt: OP_OUTARG (reg) {
186 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
188 tree->opcode = OP_MOVE;
189 tree->dreg = mono_regstate_next_int (s->rs);
190 tree->sreg1 = state->left->reg1;
191 mono_bblock_add_inst (s->cbb, tree);
193 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
196 stmt: OP_OUTARG_MEMBASE (reg) {
197 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
199 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
200 arg->offset, state->left->reg1);
203 stmt: OP_OUTARG (OP_REGVAR) {
204 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
206 tree->opcode = OP_MOVE;
207 tree->dreg = mono_regstate_next_int (s->rs);
208 tree->sreg1 = state->left->tree->dreg;
209 mono_bblock_add_inst (s->cbb, tree);
211 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
214 stmt: OP_OUTARG_MEMBASE (OP_REGVAR) {
215 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
217 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
218 arg->offset, state->left->tree->dreg);
221 stmt: OP_OUTARG (lreg) {
222 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
225 tdreg = mono_regstate_next_int (s->rs);
226 MONO_EMIT_NEW_UNALU (s, OP_MOVE, tdreg, state->left->reg2);
228 mono_call_inst_add_outarg_reg (s, call, tdreg, tree->backend.reg3, FALSE);
230 tree->opcode = OP_MOVE;
231 tree->dreg = mono_regstate_next_int (s->rs);
232 tree->sreg1 = state->left->reg1;
233 mono_bblock_add_inst (s->cbb, tree);
235 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3 + 1, FALSE);
238 stmt: OP_OUTARG_MEMBASE (lreg) {
239 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
241 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
242 arg->offset, state->left->reg2);
243 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
244 arg->offset + 4, state->left->reg1);
247 stmt: OP_OUTARG (OP_ICONST) {
248 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
250 tree->opcode = OP_ICONST;
251 tree->dreg = mono_regstate_next_int (s->rs);
252 tree->inst_c0 = state->left->tree->inst_c0;
253 mono_bblock_add_inst (s->cbb, tree);
255 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
258 stmt: OP_OUTARG_MEMBASE (OP_ICONST) {
259 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
261 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, STK_BASE,
262 arg->offset, state->left->tree->inst_c0);
265 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
266 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
268 tree->opcode = OP_MOVE;
269 tree->sreg1 = state->left->left->tree->dreg;
270 tree->dreg = mono_regstate_next_int (s->rs);
271 mono_bblock_add_inst (s->cbb, tree);
273 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
276 stmt: OP_OUTARG_MEMBASE (CEE_LDIND_REF (OP_REGVAR)) {
277 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
279 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, STK_BASE,
280 arg->offset, state->left->tree->inst_c0);
283 stmt: OP_OUTARG_MEMBASE (OP_LDADDR (OP_S390_LOADARG)) {
284 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
286 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
287 arg->offset, state->left->left->tree->dreg);
290 freg: OP_FCONV_TO_R4 (freg) "0" {
291 /* The conversion is done elsewhere */
292 MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->reg1);
295 stmt: OP_OUTARG_R4 (freg) {
296 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
298 tree->opcode = OP_S390_SETF4RET;
299 tree->dreg = mono_regstate_next_float (s->rs);
300 tree->sreg1 = state->left->reg1;
301 mono_bblock_add_inst (s->cbb, tree);
303 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE);
306 stmt: OP_OUTARG_R8 (freg),
307 stmt: OP_OUTARG (freg) {
308 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
310 tree->opcode = OP_FMOVE;
311 tree->dreg = mono_regstate_next_float (s->rs);
312 tree->sreg1 = state->left->reg1;
313 mono_bblock_add_inst (s->cbb, tree);
315 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE);
318 stmt: OP_OUTARG_MEMBASE (freg) {
319 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
321 /*----------------------------------------------*/
322 /* The length stored in size tells us whether */
323 /* we need to store a float or a double */
324 /*----------------------------------------------*/
325 if (arg->size == 4) {
326 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG,
327 STK_BASE, arg->offset,
330 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG,
331 STK_BASE, arg->offset,
336 stmt: OP_OUTARG_R4 (CEE_LDOBJ (OP_REGOFFSET)),
337 stmt: OP_OUTARG_R8 (CEE_LDOBJ (OP_REGOFFSET)) {
338 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
340 tree->opcode = OP_FMOVE;
341 tree->dreg = mono_regstate_next_float (s->rs);
342 tree->sreg1 = state->left->reg1;
343 mono_bblock_add_inst (s->cbb, tree);
345 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE);
348 freg: OP_FCONV_TO_R4 (CEE_LDOBJ (OP_REGOFFSET)) {
349 MonoInst *vt = state->left->left->tree;
351 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADR4_MEMBASE, state->reg1, vt->inst_basereg,
353 MONO_EMIT_NEW_UNALU (s, OP_FCONV_TO_R4, state->reg1, state->reg1);
356 freg: OP_FCONV_TO_R8 (CEE_LDOBJ (OP_REGOFFSET)) {
357 tree->opcode = OP_FMOVE;
358 tree->sreg1 = state->left->reg1;
359 tree->dreg = tree->backend.reg3;
360 mono_bblock_add_inst (s->cbb, tree);
364 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
365 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
366 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
367 MonoInst *vt = state->left->left->tree;
369 int start_reg = tree->sreg1;
370 int size = arg->size;
371 int soffset = vt->inst_offset;
376 treg = mono_regstate_next_int (s->rs);
377 if (start_reg != STK_BASE) {
378 MONO_EMIT_NEW_MOVE(s, STK_BASE, arg->offPrm,
379 vt->inst_basereg, soffset, size);
380 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
381 STK_BASE, arg->offPrm);
382 mono_call_inst_add_outarg_reg (s, call, treg, start_reg, FALSE);
384 MONO_EMIT_NEW_MOVE(s, STK_BASE, arg->offPrm,
385 vt->inst_basereg, soffset, size);
386 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, arg->offPrm);
387 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
388 STK_BASE, arg->offset, treg);
391 if (start_reg != STK_BASE) {
392 MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
394 MONO_OUTPUT_VTS (s, size, STK_BASE, arg->offset,
395 vt->inst_basereg, soffset);
400 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_ARGPTR)) {
401 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
402 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
403 MonoInst *vt = state->left->left->tree;
405 int start_reg = tree->sreg1;
406 int size = arg->size;
407 int soffset = vt->inst_offset;
409 if (start_reg != STK_BASE) {
410 MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
413 MONO_OUTPUT_VTS (s, size, STK_BASE, arg->offset,
414 vt->inst_basereg, soffset);
418 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_REGOFFSET)) "0" {
419 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
420 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
421 MonoInst *vt = state->left->left->tree;
423 int start_reg = tree->sreg1;
424 int size = arg->size;
425 int soffset = vt->inst_offset;
428 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_REGOFFSET))\n");
431 treg = mono_regstate_next_int (s->rs);
432 if (start_reg != STK_BASE) {
433 // MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
434 // STK_BASE, soffset);
435 MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm,
436 vt->inst_basereg, soffset, size);
437 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
438 STK_BASE, arg->offPrm);
439 mono_call_inst_add_outarg_reg (s, call, treg, start_reg, FALSE);
441 MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm,
442 vt->inst_basereg, soffset, size);
443 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, arg->offPrm);
444 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
445 STK_BASE, arg->offset, treg);
448 if (start_reg != STK_BASE) {
449 MONO_OUTPUT_VTR(s, size, start_reg, vt->inst_basereg, soffset);
451 MONO_OUTPUT_VTS(s, size, STK_BASE, arg->offset,
452 vt->inst_basereg, soffset);
457 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_LOADARG)) {
458 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
459 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
460 MonoInst *vt = state->left->left->tree;
462 int start_reg = tree->inst_basereg;
463 int size = -arg->size;
464 int soffset = vt->inst_offset;
467 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_LOADARG))\n");
468 treg = mono_regstate_next_int (s->rs);
469 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
470 MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, treg, vt->backend.arg_info);
471 MONO_EMIT_NEW_MOVE (s, STK_BASE, soffset, treg, 0, size);
472 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, soffset);
473 if (start_reg != STK_BASE) {
474 mono_call_inst_add_outarg_reg (s, call, treg, start_reg, FALSE);
476 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
477 STK_BASE, arg->offset, treg);
481 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_ARGREG)) {
482 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
483 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
484 MonoInst *vt = state->left->left->tree;
486 int base_reg = tree->inst_basereg;
487 int size = -arg->size;
488 int soffset = vt->inst_offset;
491 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_ARGREG))\n");
492 treg = mono_regstate_next_int (s->rs);
493 MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, s->frame_reg, soffset);
494 MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm, treg, 0, size);
495 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, arg->offPrm);
496 if (base_reg != STK_BASE) {
497 mono_call_inst_add_outarg_reg (s, call, treg, base_reg, FALSE);
499 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
500 STK_BASE, arg->offset, treg);
504 stmt: OP_OUTARG_VT (OP_ICONST) {
505 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
506 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
508 int start_reg = tree->sreg1;
509 int size = arg->size;
510 int nregs = size / 4;
512 //printf("OP_OUTARG_VT(OP_ICONST)\n");
513 if (start_reg != STK_BASE) {
515 tree->opcode = OP_ICONST;
516 tree->dreg = mono_regstate_next_int (s->rs);
517 tree->inst_c0 = state->left->tree->inst_c0;
518 mono_bblock_add_inst (s->cbb, tree);
519 mono_call_inst_add_outarg_reg (s, call, tree->dreg, start_reg, FALSE);
522 MONO_OUTPUT_VTS (s, size, STK_BASE, tree->inst_c0,
523 s->frame_reg, tree->inst_offset);
527 stmt: OP_OUTARG_VT (reg) {
528 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
529 MonoCallArgParm *arg = (MonoCallArgParm *) tree;
530 MonoInst *vt = state->left->left->tree;
531 int start_reg = tree->sreg1;
532 int size = arg->size;
533 int soffset = vt->inst_offset;
538 treg = mono_regstate_next_int (s->rs);
539 if (start_reg != STK_BASE) {
540 MONO_EMIT_NEW_MOVE (s, STK_BASE, arg->offPrm, state->left->reg1,
542 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
543 STK_BASE, arg->offPrm);
544 mono_call_inst_add_outarg_reg (s, call, treg, start_reg, FALSE);
546 MONO_EMIT_NEW_MOVE (s, STK_BASE, soffset+size, state->left->reg1,
548 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
550 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
551 STK_BASE, arg->offset, treg);
554 if (start_reg != STK_BASE) {
555 MONO_OUTPUT_VTR (s, size, start_reg, STK_BASE, soffset);
557 treg = mono_regstate_next_int (s->rs);
558 MONO_OUTPUT_VTS (s, size, STK_BASE, soffset, treg,
559 state->left->tree->inst_offset);
560 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
566 stmt: OP_OUTARG_VT (OP_REFANYTYPE (reg)) "0" {
567 //printf("OP_OUTARG_VT (OP_REFANYTYPE (base))\n");
568 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->tree->sreg1, state->left->left->reg1,
569 G_STRUCT_OFFSET (MonoTypedRef, type));
572 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
573 /* nothing to do: the value is already on the FP stack */
576 stmt: CEE_BNE_UN (fpcflags) {
577 tree->opcode = OP_FBNE_UN;
578 mono_bblock_add_inst (s->cbb, tree);
581 stmt: CEE_BEQ (fpcflags) {
582 tree->opcode = OP_FBEQ;
583 mono_bblock_add_inst (s->cbb, tree);
586 stmt: CEE_BLT (fpcflags) {
587 tree->opcode = OP_FBLT;
588 mono_bblock_add_inst (s->cbb, tree);
591 stmt: CEE_BLT_UN (fpcflags) {
592 tree->opcode = OP_FBLT_UN;
593 mono_bblock_add_inst (s->cbb, tree);
596 stmt: CEE_BGT (fpcflags) {
597 tree->opcode = OP_FBGT;
598 mono_bblock_add_inst (s->cbb, tree);
601 stmt: CEE_BGT_UN (fpcflags) {
602 tree->opcode = OP_FBGT_UN;
603 mono_bblock_add_inst (s->cbb, tree);
606 stmt: CEE_BGE (fpcflags) {
607 tree->opcode = OP_FBGE;
608 mono_bblock_add_inst (s->cbb, tree);
611 stmt: CEE_BGE_UN (fpcflags) {
612 tree->opcode = OP_FBGE_UN;
613 mono_bblock_add_inst (s->cbb, tree);
616 stmt: CEE_BLE (fpcflags) {
617 tree->opcode = OP_FBLE;
618 mono_bblock_add_inst (s->cbb, tree);
621 stmt: CEE_BLE_UN (fpcflags) {
622 tree->opcode = OP_FBLE_UN;
623 mono_bblock_add_inst (s->cbb, tree);
626 stmt: CEE_POP (freg) "0" {
630 freg: OP_LCONV_TO_R8 (lreg) {
631 /* nothing to do - emulated */
634 freg: OP_LCONV_TO_R4 (lreg) {
635 /* nothing to do - emulated */
638 freg: OP_LCONV_TO_R_UN (lreg) {
639 /* nothing to do - emulated */
642 freg: OP_FREM (freg, freg) {
643 /* nothing to do - emulated */
646 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
647 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
648 state->left->right->reg1);
651 reg: OP_CLT (OP_COMPARE (freg, freg)) {
652 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
653 state->left->right->reg1);
656 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
657 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
658 state->left->right->reg1);
661 reg: OP_CGT (OP_COMPARE (freg, freg)) {
662 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
663 state->left->right->reg1);
666 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
667 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
668 state->left->right->reg1);
671 base: OP_S390_STKARG "0" {
674 treg = mono_regstate_next_int (s->rs);
675 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
676 tree->inst_offset = state->tree->inst_offset;
677 tree->inst_basereg = treg;
680 reg: OP_LDADDR (OP_S390_ARGREG),
681 reg: CEE_LDOBJ (OP_S390_ARGREG) "0" {
682 MONO_EMIT_LOAD_MEMBASE (s, tree, state->reg1, s->frame_reg, state->left->tree->inst_offset);
685 base: OP_LDADDR (OP_S390_LOADARG) "0" {
688 treg = mono_regstate_next_int (s->rs);
689 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
690 MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, treg, state->left->tree->backend.arg_info);
691 tree->inst_offset = 0;
692 tree->inst_basereg = treg;
695 base: OP_LDADDR (OP_S390_ARGPTR) "0" {
698 treg = mono_regstate_next_int (s->rs);
699 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg,
700 state->left->tree->inst_offset);
701 tree->inst_offset = 0;
702 tree->inst_basereg = treg;
705 base: OP_LDADDR (OP_S390_STKARG) "0" {
708 printf("base: OP_LDADDR(OP_S390_STKARG) 0\n");
709 treg = mono_regstate_next_int (s->rs);
710 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
711 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, treg,
712 state->left->tree->inst_offset);
713 tree->inst_offset = 0;
714 tree->inst_basereg = treg;
717 reg: OP_LDADDR (OP_S390_LOADARG) {
720 treg = mono_regstate_next_int (s->rs);
721 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
722 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, treg, state->left->tree->inst_offset);
725 reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
726 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
727 state->left->tree->inst_offset);
728 tree->inst_offset = 0;
729 tree->inst_basereg = state->reg1;
732 reg: OP_LDADDR (OP_S390_STKARG) "2" {
733 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, state->reg1, s->frame_reg);
734 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
735 (state->left->tree->backend.arg_info +
736 state->left->tree->inst_offset));
737 tree->inst_offset = 0;
738 tree->inst_basereg = state->reg1;
741 reg: CEE_LDOBJ (OP_S390_LOADARG) "1" {
742 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
743 state->left->tree->inst_offset);
746 reg: CEE_LDOBJ (OP_S390_ARGPTR) "1" {
747 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
748 state->left->tree->inst_offset);
751 reg: CEE_LDOBJ (OP_S390_STKARG) "1" {
752 printf("reg: CEE_LDOBJ(OP_S390_STKARG)\n");
753 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, state->reg1, s->frame_reg);
754 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
755 (state->left->tree->inst_offset +
756 state->left->tree->backend.arg_info));
757 tree->inst_offset = 0;
758 tree->inst_basereg = state->reg1;
761 base: CEE_LDOBJ (OP_S390_ARGPTR) "0" {
764 treg = mono_regstate_next_int (s->rs);
765 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg,
766 state->left->tree->inst_offset);
767 tree->inst_offset = 0;
768 tree->inst_basereg = treg;
771 base: CEE_LDOBJ (OP_S390_STKARG) "0" {
774 treg = mono_regstate_next_int (s->rs);
775 MONO_EMIT_NEW_UNALU (s, OP_S390_BKCHAIN, treg, s->frame_reg);
776 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, treg, state->left->tree->backend.arg_info);
777 MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, treg, state->left->tree->inst_offset);
778 tree->inst_offset = 0;
779 tree->inst_basereg = treg;
782 reg: OP_ATOMIC_ADD_NEW_I4 (base, reg),
783 reg: OP_ATOMIC_ADD_I4 (base, reg) {
784 tree->opcode = tree->opcode;
785 tree->inst_basereg = state->left->tree->inst_basereg;
786 tree->inst_offset = state->left->tree->inst_offset;
787 tree->dreg = state->reg1;
788 tree->sreg2 = state->right->reg1;
790 mono_bblock_add_inst (s->cbb, tree);
793 reg: OP_ATOMIC_EXCHANGE_I4 (base, reg) {
794 tree->opcode = OP_ATOMIC_EXCHANGE_I4;
795 tree->dreg = state->reg1;
796 tree->sreg2 = state->right->reg1;
797 tree->inst_basereg = state->left->tree->inst_basereg;
798 tree->inst_offset = state->left->tree->inst_offset;
800 mono_bblock_add_inst (s->cbb, tree);