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);
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 lreg: OP_LADD_OVF (lreg, lreg) "0" {
34 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
37 lreg: OP_LADD_OVF_UN (lreg, lreg) "0" {
38 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
41 #reg: OP_LSUB_OVF (lreg, lreg) "0" {
42 # /* SBB sets the condition code */
43 # MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
44 # MONO_EMIT_NEW_BIALU (s, OP_SUB_OVF_CARRY, state->reg2, state->left->reg2, state->right->reg2);
47 lreg: OP_LSUB_OVF (lreg, lreg) "0" {
48 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
51 lreg: OP_LSUB_OVF_UN (lreg, lreg) "0" {
52 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
55 reg: CEE_ADD_OVF (reg, reg) "0" {
56 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
59 reg: CEE_ADD_OVF_UN (reg, reg) "0" {
60 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
63 reg: CEE_SUB_OVF (reg, reg) "0" {
64 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
67 reg: CEE_SUB_OVF_UN (reg, reg) "0" {
68 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
71 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
72 /*------------------------------------------------------*/
73 /* this should only happen for methods returning a long */
74 /* S/390 ABI uses r2/r3 for returning 64-bit integers */
75 /*------------------------------------------------------*/
76 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r2, state->right->reg1);
77 MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r3, state->right->reg2);
80 freg: OP_LCONV_TO_R8 (lreg) {
81 tree->dreg = state->reg1;
82 tree->sreg1 = state->left->reg1;
83 tree->sreg2 = state->left->reg2;
84 mono_bblock_add_inst (s->cbb, tree);
87 freg: OP_LCONV_TO_R4 (lreg) {
88 tree->dreg = state->reg1;
89 tree->sreg1 = state->left->reg1;
90 tree->sreg2 = state->left->reg2;
91 mono_bblock_add_inst (s->cbb, tree);
94 freg: CEE_CONV_R_UN (reg) {
95 tree->dreg = state->reg1;
96 tree->sreg1 = state->left->reg1;
97 mono_bblock_add_inst (s->cbb, tree);
100 freg: CEE_CONV_R_UN (reg) {
101 mono_bblock_add_inst (s->cbb, tree);
104 stmt: OP_MEMCPY (reg, reg) "0" {
105 int size = tree->unused;
107 MONO_EMIT_NEW_MOVE (s, state->left->reg1, 0,
108 state->right->reg1, 0, size);
111 stmt: OP_MEMCPY (base, base) "0" {
112 int size = tree->unused;
114 MONO_EMIT_NEW_MOVE (s, state->left->tree->sreg1,
115 state->left->tree->inst_offset,
116 state->right->tree->sreg1,
117 state->right->tree->inst_offset,
121 reg: OP_LOCALLOC (OP_ICONST) {
122 /* microcoded in mini-s390.c */
123 tree->sreg1 = mono_regstate_next_int (s->rs);
124 tree->dreg = state->reg1;
125 MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
126 mono_bblock_add_inst (s->cbb, tree);
129 reg: OP_LOCALLOC (reg) {
130 tree->dreg = state->reg1;
131 tree->sreg1 = state->left->reg1;
132 mono_bblock_add_inst (s->cbb, tree);
135 stmt: OP_SETRET (reg) {
136 tree->opcode = OP_MOVE;
137 tree->sreg1 = state->left->reg1;
138 tree->dreg = s390_r2;
139 mono_bblock_add_inst (s->cbb, tree);
142 stmt: OP_SETRET (lreg) {
143 tree->opcode = OP_SETLRET;
144 tree->sreg1 = state->left->reg1;
145 tree->sreg2 = state->left->reg2;
146 mono_bblock_add_inst (s->cbb, tree);
149 stmt: OP_SETRET (freg) {
150 if (mono_method_signature (s->method)->ret->type == MONO_TYPE_R4) {
151 tree->opcode = OP_S390_SETF4RET;
152 tree->sreg1 = state->left->reg1;
153 tree->dreg = s390_f0;
155 tree->opcode = OP_FMOVE;
156 tree->sreg1 = state->left->reg1;
157 tree->dreg = s390_f0;
159 mono_bblock_add_inst (s->cbb, tree);
162 stmt: OP_SETRET (OP_ICONST) {
163 tree->opcode = OP_ICONST;
164 tree->inst_c0 = state->left->tree->inst_c0;
165 tree->dreg = s390_r2;
166 mono_bblock_add_inst (s->cbb, tree);
169 #lreg: OP_LSUB_OVF_UN (lreg, lreg) "0" {
170 # /*----------------------------------------------------------------------*/
171 # /* SBB sets the condition code - CC 0 or 1 indicates Borrow == Overflow */
172 # /*----------------------------------------------------------------------*/
173 # MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
174 # MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
175 # MONO_EMIT_NEW_COND_EXC (s, NC, "OverflowException");
178 stmt: OP_OUTARG (reg) {
179 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
181 tree->opcode = OP_SETREG;
182 tree->dreg = mono_regstate_next_int (s->rs);
183 tree->sreg1 = state->left->reg1;
184 mono_bblock_add_inst (s->cbb, tree);
186 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
189 stmt: OP_OUTARG_MEMBASE (reg) {
190 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
192 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
193 argParm->offset, state->left->reg1);
198 stmt: OP_OUTARG (OP_REGVAR) {
199 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
200 tree->opcode = OP_SETREG;
201 tree->dreg = mono_regstate_next_int (s->rs);
202 tree->sreg1 = state->left->tree->dreg;
203 mono_bblock_add_inst (s->cbb, tree);
205 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
208 stmt: OP_OUTARG_MEMBASE (OP_REGVAR) {
209 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
211 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
212 argParm->offset, state->left->tree->dreg);
217 #stmt: OP_OUTARG (reg) {
218 # if (tree->inst_imm) {
219 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->reg1);
222 # tree->opcode = OP_SETREG;
223 # tree->dreg = tree->unused;
224 # tree->sreg1 = state->left->reg1;
225 # mono_bblock_add_inst (s->cbb, tree);
228 #stmt: OP_OUTARG (OP_REGVAR) {
229 # if (tree->inst_imm) {
230 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->tree->dreg);
233 # tree->opcode = OP_SETREG;
234 # tree->dreg = tree->unused;
235 # tree->sreg1 = state->left->tree->dreg;
236 # mono_bblock_add_inst (s->cbb, tree);
239 stmt: OP_OUTARG (lreg) {
240 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
242 tdreg = mono_regstate_next_int (s->rs);
243 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
245 mono_call_inst_add_outarg_reg (call, tdreg, tree->unused, FALSE);
247 tree->opcode = OP_SETREG;
248 tree->dreg = mono_regstate_next_int (s->rs);
249 tree->sreg1 = state->left->reg1;
250 mono_bblock_add_inst (s->cbb, tree);
252 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused + 1, FALSE);
253 # tree->dreg = tree->unused + 1;
256 stmt: OP_OUTARG_MEMBASE (lreg) {
257 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
259 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
260 argParm->offset, state->left->reg2);
261 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
262 argParm->offset + 4, state->left->reg1);
266 #stmt: OP_OUTARG (lreg) {
267 # if (tree->inst_imm) {
268 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->reg2);
269 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm + 4, state->left->reg1);
272 # MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
273 # tree->opcode = OP_SETREG;
274 # tree->dreg = tree->unused + 1;
275 # tree->sreg1 = state->left->reg1;
276 # mono_bblock_add_inst (s->cbb, tree);
279 stmt: OP_OUTARG (OP_ICONST) {
280 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
281 tree->opcode = OP_ICONST;
282 tree->dreg = mono_regstate_next_int (s->rs);
283 tree->inst_c0 = state->left->tree->inst_c0;
284 mono_bblock_add_inst (s->cbb, tree);
286 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
289 stmt: OP_OUTARG_MEMBASE (OP_ICONST) {
290 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
292 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, STK_BASE,
293 argParm->offset, state->left->tree->inst_c0);
298 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
299 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
300 tree->opcode = OP_SETREG;
301 tree->sreg1 = state->left->left->tree->dreg;
302 tree->dreg = mono_regstate_next_int (s->rs);
303 mono_bblock_add_inst (s->cbb, tree);
305 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
308 stmt: OP_OUTARG_MEMBASE (CEE_LDIND_REF (OP_REGVAR)) {
309 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
311 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, STK_BASE,
312 argParm->offset, state->left->tree->inst_c0);
317 #stmt: OP_OUTARG (OP_ICONST) {
318 # if (tree->inst_imm) {
319 # MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, STK_BASE, tree->inst_imm, state->left->tree->inst_c0);
322 # tree->opcode = OP_SETREGIMM;
323 # tree->dreg = tree->unused;
324 # tree->inst_c0 = state->left->tree->inst_c0;
325 # mono_bblock_add_inst (s->cbb, tree);
328 #stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
329 # if (tree->inst_imm) {
330 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->left->tree->dreg);
333 # tree->opcode = OP_SETREG;
334 # tree->sreg1 = state->left->left->tree->dreg;
335 # tree->dreg = tree->unused;
336 # mono_bblock_add_inst (s->cbb, tree);
339 stmt: OP_OUTARG (OP_LDADDR (OP_S390_LOADARG)) {
340 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, tree->unused,
341 state->left->left->tree->sreg1,
342 state->left->left->tree->inst_offset);
345 stmt: OP_OUTARG_MEMBASE (OP_LDADDR (OP_S390_LOADARG)) {
346 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
348 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE,
349 argParm->offset, state->left->left->tree->dreg);
354 #stmt: OP_OUTARG (OP_LDADDR (OP_S390_LOADARG)) {
355 # if (tree->inst_imm) {
356 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->left->tree->dreg);
359 # MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, tree->unused,
360 # state->left->left->tree->sreg1,
361 # state->left->left->tree->inst_offset);
364 stmt: OP_OUTARG_R4 (freg) {
365 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
367 tree->opcode = OP_FCONV_TO_R4;
368 tree->dreg = mono_regstate_next_float (s->rs);
369 tree->sreg1 = state->left->reg1;
370 mono_bblock_add_inst (s->cbb, tree);
372 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, TRUE);
375 stmt: OP_OUTARG_R8 (freg),
376 stmt: OP_OUTARG (freg) {
377 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
379 tree->opcode = OP_SETFREG;
380 tree->dreg = mono_regstate_next_float (s->rs);
381 tree->sreg1 = state->left->reg1;
382 mono_bblock_add_inst (s->cbb, tree);
384 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, TRUE);
387 stmt: OP_OUTARG_MEMBASE (freg) {
388 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
390 /*----------------------------------------------*/
391 /* The length stored in size tells us whether */
392 /* we need to store a float or a double */
393 /*----------------------------------------------*/
394 if (argParm->size == 4) {
395 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG,
396 STK_BASE, argParm->offset,
399 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG,
400 STK_BASE, argParm->offset,
406 #stmt: OP_OUTARG_R4 (freg) {
407 # if (tree->inst_imm) {
408 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->reg1);
411 # tree->opcode = OP_SETFREG;
412 # tree->sreg1 = state->left->reg1;
413 # tree->dreg = tree->unused;
414 # mono_bblock_add_inst (s->cbb, tree);
417 #stmt: OP_OUTARG_R8 (freg) {
418 # if (tree->inst_imm) {
419 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, STK_BASE,
420 # tree->inst_imm, state->left->reg1);
423 # tree->opcode = OP_SETFREG;
424 # tree->sreg1 = state->left->reg1;
425 # tree->dreg = tree->unused;
426 # mono_bblock_add_inst (s->cbb, tree);
429 stmt: OP_OUTARG_R4 (CEE_LDOBJ (OP_REGOFFSET)),
430 stmt: OP_OUTARG_R8 (CEE_LDOBJ (OP_REGOFFSET)) {
431 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
433 tree->opcode = OP_SETFREG;
434 tree->dreg = mono_regstate_next_float (s->rs);
435 tree->sreg1 = state->left->reg1;
436 mono_bblock_add_inst (s->cbb, tree);
438 mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, TRUE);
441 #stmt: OP_OUTARG_R8 (CEE_LDOBJ (OP_REGOFFSET)) {
442 # if (tree->inst_imm) {
443 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, STK_BASE,
444 # tree->inst_imm, state->left->reg1);
447 # tree->opcode = OP_SETFREG;
448 # tree->sreg1 = state->left->reg1;
449 # tree->dreg = tree->unused;
450 # mono_bblock_add_inst (s->cbb, tree);
453 freg: OP_FCONV_TO_R4 (CEE_LDOBJ (OP_REGOFFSET)) {
454 MonoInst *vt = state->left->left->tree;
456 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADR4_MEMBASE, state->reg1, vt->inst_basereg,
458 MONO_EMIT_NEW_UNALU (s, OP_FCONV_TO_R4, state->reg1, state->reg1);
461 freg: OP_FCONV_TO_R8 (CEE_LDOBJ (OP_REGOFFSET)) {
462 tree->opcode = OP_SETFREG;
463 tree->sreg1 = state->left->reg1;
464 tree->dreg = tree->unused;
465 mono_bblock_add_inst (s->cbb, tree);
469 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
470 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
471 MonoInst *vt = state->left->left->tree;
472 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
474 int start_reg = tree->sreg1;
475 int size = argParm->size;
476 int soffset = vt->inst_offset;
481 treg = mono_regstate_next_int (s->rs);
482 if (start_reg != STK_BASE) {
483 MONO_EMIT_NEW_MOVE(s, STK_BASE, argParm->offPrm,
484 vt->inst_basereg, soffset, size);
485 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
486 STK_BASE, argParm->offPrm);
487 mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
489 MONO_EMIT_NEW_MOVE(s, STK_BASE, argParm->offPrm+sizeof(gpointer),
490 vt->inst_basereg, soffset, size);
491 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
492 argParm->offPrm+sizeof(gpointer));
493 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
494 STK_BASE, argParm->offPrm, treg);
497 if (start_reg != STK_BASE) {
498 MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
500 MONO_OUTPUT_VTS (s, size, STK_BASE, argParm->offset,
501 vt->inst_basereg, soffset);
507 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_ARGPTR)) {
508 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
509 MonoInst *vt = state->left->left->tree;
510 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
512 int start_reg = tree->sreg1;
513 int size = argParm->size;
514 int soffset = vt->inst_offset;
517 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_ARGPTR))\n");
520 treg = mono_regstate_next_int (s->rs);
521 if (start_reg != STK_BASE) {
522 MONO_EMIT_NEW_MOVE (s, STK_BASE, argParm->offset,
523 vt->inst_basereg, soffset, size);
524 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
525 STK_BASE, argParm->offPrm);
526 mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
528 MONO_EMIT_NEW_MOVE (s, STK_BASE,
529 argParm->offset+sizeof(gpointer),
530 vt->inst_basereg, soffset, size);
531 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
532 argParm->offset+sizeof(gpointer));
533 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
534 STK_BASE, argParm->offset, treg);
537 if (start_reg != STK_BASE) {
538 MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
540 MONO_OUTPUT_VTS (s, size, STK_BASE, argParm->offset,
541 vt->inst_basereg, soffset);
547 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_REGOFFSET)) "0" {
548 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
549 MonoInst *vt = state->left->left->tree;
550 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
552 int start_reg = tree->sreg1;
553 int size = argParm->size;
554 int soffset = vt->inst_offset;
557 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_REGOFFSET))\n");
560 treg = mono_regstate_next_int (s->rs);
561 if (start_reg != STK_BASE) {
562 // MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
563 // STK_BASE, soffset);
564 MONO_EMIT_NEW_MOVE (s, STK_BASE, argParm->offPrm,
565 vt->inst_basereg, soffset, size);
566 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
567 STK_BASE, argParm->offPrm);
568 mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
570 MONO_EMIT_NEW_MOVE (s, STK_BASE,
571 argParm->offPrm+sizeof(gpointer),
572 vt->inst_basereg, soffset, size);
573 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
574 argParm->offPrm+sizeof(gpointer));
575 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
576 STK_BASE, argParm->offPrm, treg);
579 if (start_reg != STK_BASE) {
580 MONO_OUTPUT_VTR(s, size, start_reg, vt->inst_basereg, soffset);
582 MONO_OUTPUT_VTS(s, size, STK_BASE, argParm->offset,
583 vt->inst_basereg, soffset);
589 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_LOADARG)) {
590 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
591 MonoInst *vt = state->left->left->tree;
592 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
594 int start_reg = tree->sreg1;
595 int size = -argParm->size;
596 int soffset = vt->inst_offset;
599 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_LOADARG))\n");
600 treg = mono_regstate_next_int (s->rs);
601 if (start_reg != STK_BASE) {
602 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE, soffset);
603 MONO_EMIT_NEW_MOVE (s, STK_BASE, argParm->offPrm, treg, 0, size);
604 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
605 STK_BASE, argParm->offPrm);
606 mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
608 MONO_EMIT_NEW_MOVE (s, STK_BASE,
609 argParm->offset+sizeof(gpointer),
610 vt->inst_basereg, soffset, size);
611 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
612 argParm->offset+sizeof(gpointer));
613 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
614 STK_BASE, argParm->offset, treg);
619 stmt: OP_OUTARG_VT (OP_ICONST) {
620 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
621 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
622 int start_reg = tree->sreg1;
623 int size = argParm->size;
624 int nregs = size / 4;
626 //printf("OP_OUTARG_VT(OP_ICONST)\n");
627 if (start_reg != STK_BASE) {
629 tree->opcode = OP_SETREGIMM;
630 tree->dreg = mono_regstate_next_int (s->rs);
631 tree->inst_c0 = state->left->tree->inst_c0;
632 mono_bblock_add_inst (s->cbb, tree);
633 mono_call_inst_add_outarg_reg (call, tree->dreg, start_reg, FALSE);
636 MONO_OUTPUT_VTS (s, size, STK_BASE, tree->inst_c0,
637 s->frame_reg, tree->inst_offset);
642 stmt: OP_OUTARG_VT (reg) {
643 MonoCallInst *call = (MonoCallInst*) tree->inst_right;
644 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
645 MonoInst *vt = state->left->left->tree;
646 int start_reg = tree->sreg1;
647 int size = argParm->size;
648 int soffset = vt->inst_offset;
653 treg = mono_regstate_next_int (s->rs);
654 if (start_reg != STK_BASE) {
655 MONO_EMIT_NEW_MOVE (s, STK_BASE, argParm->offPrm, state->left->reg1,
657 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg,
658 STK_BASE, argParm->offPrm);
659 mono_call_inst_add_outarg_reg (call, treg, start_reg, FALSE);
661 MONO_EMIT_NEW_MOVE (s, STK_BASE, soffset+size, state->left->reg1,
663 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
665 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG,
666 STK_BASE, argParm->offset, treg);
669 if (start_reg != STK_BASE) {
670 MONO_OUTPUT_VTR (s, size, start_reg, STK_BASE, soffset);
672 MONO_OUTPUT_VTS (s, size, STK_BASE, soffset, treg,
673 state->left->tree->inst_offset);
674 treg = mono_regstate_next_int (s->rs);
675 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, STK_BASE,
682 stmt: OP_OUTARG_VT (OP_REFANYTYPE (reg)) "0" {
683 MonoS390ArgParm *argParm = (MonoS390ArgParm *) tree->unused;
685 //printf("OP_OUTARG_VT (OP_REFANYTYPE (base))\n");
686 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->tree->sreg1, state->left->left->reg1,
687 G_STRUCT_OFFSET (MonoTypedRef, type));
691 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
692 /* nothing to do: the value is already on the FP stack */
695 stmt: CEE_BNE_UN (fpcflags) {
696 tree->opcode = OP_FBNE_UN;
697 mono_bblock_add_inst (s->cbb, tree);
700 stmt: CEE_BEQ (fpcflags) {
701 tree->opcode = OP_FBEQ;
702 mono_bblock_add_inst (s->cbb, tree);
705 stmt: CEE_BLT (fpcflags) {
706 tree->opcode = OP_FBLT;
707 mono_bblock_add_inst (s->cbb, tree);
710 stmt: CEE_BLT_UN (fpcflags) {
711 tree->opcode = OP_FBLT_UN;
712 mono_bblock_add_inst (s->cbb, tree);
715 stmt: CEE_BGT (fpcflags) {
716 tree->opcode = OP_FBGT;
717 mono_bblock_add_inst (s->cbb, tree);
720 stmt: CEE_BGT_UN (fpcflags) {
721 tree->opcode = OP_FBGT_UN;
722 mono_bblock_add_inst (s->cbb, tree);
725 stmt: CEE_BGE (fpcflags) {
726 tree->opcode = OP_FBGE;
727 mono_bblock_add_inst (s->cbb, tree);
730 stmt: CEE_BGE_UN (fpcflags) {
731 tree->opcode = OP_FBGE_UN;
732 mono_bblock_add_inst (s->cbb, tree);
735 stmt: CEE_BLE (fpcflags) {
736 tree->opcode = OP_FBLE;
737 mono_bblock_add_inst (s->cbb, tree);
740 stmt: CEE_BLE_UN (fpcflags) {
741 tree->opcode = OP_FBLE_UN;
742 mono_bblock_add_inst (s->cbb, tree);
745 stmt: CEE_POP (freg) "0" {
749 freg: OP_LCONV_TO_R8 (lreg) {
750 /* nothing to do - emulated */
753 freg: OP_LCONV_TO_R4 (lreg) {
754 /* nothing to do - emulated */
757 freg: OP_LCONV_TO_R_UN (lreg) {
758 /* nothing to do - emulated */
761 freg: OP_FREM (freg, freg) {
762 /* nothing to do - emulated */
765 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
766 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
767 state->left->right->reg1);
770 reg: OP_CLT (OP_COMPARE (freg, freg)) {
771 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
772 state->left->right->reg1);
775 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
776 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
777 state->left->right->reg1);
780 reg: OP_CGT (OP_COMPARE (freg, freg)) {
781 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
782 state->left->right->reg1);
785 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
786 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
787 state->left->right->reg1);
790 base: OP_S390_STKARG "0" {
793 treg = mono_regstate_next_int (s->rs);
794 MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, STK_BASE, 0);
795 // MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, s->frame_reg, 0);
796 tree->inst_offset = state->tree->inst_offset;
797 tree->inst_basereg = treg;
800 reg: OP_LDADDR (OP_S390_ARGREG),
801 reg: CEE_LDOBJ (OP_S390_ARGREG) "0" {
804 MONO_EMIT_LOAD_MEMBASE (s, tree, state->reg1, s->frame_reg, state->left->tree->inst_offset);
807 base: OP_LDADDR (OP_S390_LOADARG) "0" {
810 treg = mono_regstate_next_int (s->rs);
811 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg,
812 state->left->tree->inst_offset);
813 tree->inst_offset = 0;
814 tree->inst_basereg = treg;
817 base: OP_LDADDR (OP_S390_ARGPTR) "0" {
820 treg = mono_regstate_next_int (s->rs);
821 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg,
822 state->left->tree->inst_offset);
823 tree->inst_offset = 0;
824 tree->inst_basereg = treg;
827 base: OP_LDADDR (OP_S390_STKARG) "0" {
830 treg = mono_regstate_next_int (s->rs);
831 MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, STK_BASE, 0);
832 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, treg,
833 state->left->tree->inst_offset);
834 tree->inst_offset = 0;
835 tree->inst_basereg = treg;
838 reg: OP_LDADDR (OP_S390_LOADARG) "2" {
839 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
840 state->left->tree->inst_offset);
841 tree->inst_offset = 0;
842 tree->inst_basereg = state->reg1;
845 reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
846 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
847 state->left->tree->inst_offset);
848 tree->inst_offset = 0;
849 tree->inst_basereg = state->reg1;
852 reg: OP_LDADDR (OP_S390_STKARG) "2" {
853 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
854 (s->stack_offset + state->left->tree->unused));
855 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
856 state->left->tree->inst_offset);
857 tree->inst_offset = 0;
858 tree->inst_basereg = state->reg1;
861 reg: CEE_LDOBJ (OP_S390_LOADARG) "1" {
862 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
863 state->left->tree->inst_offset);
866 reg: CEE_LDOBJ (OP_S390_ARGPTR) "1" {
867 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
868 state->left->tree->inst_offset);
871 reg: CEE_LDOBJ (OP_S390_STKARG) "1" {
872 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
873 (s->stack_offset + state->left->tree->unused));
874 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
875 state->left->tree->inst_offset);
876 tree->inst_offset = 0;
877 tree->inst_basereg = state->reg1;
880 base: CEE_LDOBJ (OP_S390_ARGPTR) "0" {
883 treg = mono_regstate_next_int (s->rs);
884 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg,
885 state->left->tree->inst_offset);
886 tree->inst_offset = 0;
887 tree->inst_basereg = treg;
890 base: CEE_LDOBJ (OP_S390_STKARG) "0" {
893 treg = mono_regstate_next_int (s->rs);
894 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, treg, s->frame_reg,
895 (s->stack_offset + state->left->tree->unused));
896 MONO_EMIT_NEW_LOAD_MEMBASE (s, treg, treg, state->left->tree->inst_offset);
897 tree->inst_offset = 0;
898 tree->inst_basereg = treg;
901 reg: OP_ATOMIC_ADD_NEW_I4 (base, reg),
902 reg: OP_ATOMIC_ADD_I4 (base, reg) {
903 tree->opcode = tree->opcode;
904 tree->inst_basereg = state->left->tree->inst_basereg;
905 tree->inst_offset = state->left->tree->inst_offset;
906 tree->dreg = state->reg1;
907 tree->sreg2 = state->right->reg1;
909 mono_bblock_add_inst (s->cbb, tree);
912 reg: OP_ATOMIC_EXCHANGE_I4 (base, reg) {
913 tree->opcode = OP_ATOMIC_EXCHANGE_I4;
914 tree->dreg = state->reg1;
915 tree->sreg2 = state->right->reg1;
916 tree->inst_basereg = state->left->tree->inst_basereg;
917 tree->inst_offset = state->left->tree->inst_offset;
919 mono_bblock_add_inst (s->cbb, tree);