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 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;
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;
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;
90 mono_bblock_add_inst (s->cbb, tree);
93 stmt: OP_OUTARG (reg) {
95 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
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);
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);
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);
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);
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);
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);
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);
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;
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);
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,
204 MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg + i, tmpr);
205 soffset += sizeof (gpointer);
208 mini_emit_memcpy (s, s->frame_reg, tree->inst_imm,
209 vt->inst_basereg, soffset, size, 0);
214 stmt: OP_OUTARG_VT (OP_ICONST) {
215 int start_reg = tree->sreg1;
216 int size = tree->unused;
217 int nregs = size / 4;
219 if (start_reg != STK_BASE) {
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);
227 mini_emit_memcpy (s, s->frame_reg, tree->inst_c0, STK_BASE,
228 tree->inst_offset, size, 0);
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;
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);
248 if (start_reg != STK_BASE) {
249 for (i = 0; i < nregs; ++i) {
250 MONO_EMIT_NEW_LOAD_MEMBASE(s, start_reg + i,
253 soffset += sizeof(gpointer);
257 tmpr = mono_regstate_next_int (s->rs);
258 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
260 mini_emit_memcpy (s, s->frame_reg, soffset, tmpr,
261 tree->sreg2, size, 0);
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" {
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" {
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" {
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" {
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" {
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" {
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" {
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" {
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;