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->sreg2;
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->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);
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->sreg2;
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->sreg2;
234 int size = tree->unused;
235 int nregs = size / 4;
236 int soffset = tree->inst_imm;
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,
242 soffset += sizeof(gpointer);
245 mini_emit_memcpy (s, s->frame_reg, tree->inst_imm, tree->sreg1,
250 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
251 /* nothing to do: the value is already on the FP stack */
254 stmt: CEE_BNE_UN (fpcflags) {
255 tree->opcode = OP_FBNE_UN;
256 mono_bblock_add_inst (s->cbb, tree);
259 stmt: CEE_BEQ (fpcflags) {
260 tree->opcode = OP_FBEQ;
261 mono_bblock_add_inst (s->cbb, tree);
264 stmt: CEE_BLT (fpcflags) {
265 tree->opcode = OP_FBLT;
266 mono_bblock_add_inst (s->cbb, tree);
269 stmt: CEE_BLT_UN (fpcflags) {
270 tree->opcode = OP_FBLT_UN;
271 mono_bblock_add_inst (s->cbb, tree);
274 stmt: CEE_BGT (fpcflags) {
275 tree->opcode = OP_FBGT;
276 mono_bblock_add_inst (s->cbb, tree);
279 stmt: CEE_BGT_UN (fpcflags) {
280 tree->opcode = OP_FBGT_UN;
281 mono_bblock_add_inst (s->cbb, tree);
284 stmt: CEE_BGE (fpcflags) {
285 tree->opcode = OP_FBGE;
286 mono_bblock_add_inst (s->cbb, tree);
289 stmt: CEE_BGE_UN (fpcflags) {
290 tree->opcode = OP_FBGE_UN;
291 mono_bblock_add_inst (s->cbb, tree);
294 stmt: CEE_BLE (fpcflags) {
295 tree->opcode = OP_FBLE;
296 mono_bblock_add_inst (s->cbb, tree);
299 stmt: CEE_BLE_UN (fpcflags) {
300 tree->opcode = OP_FBLE_UN;
301 mono_bblock_add_inst (s->cbb, tree);
304 stmt: CEE_POP (freg) "0" {
308 freg: OP_LCONV_TO_R8 (lreg) {
309 /* nothing to do - emulated */
312 freg: OP_LCONV_TO_R4 (lreg) {
313 /* nothing to do - emulated */
316 freg: OP_LCONV_TO_R_UN (lreg) {
317 /* nothing to do - emulated */
320 freg: OP_FREM (freg, freg) {
321 /* nothing to do - emulated */
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);
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);
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);
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);
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);
349 base: OP_REGOFFSET "0" {
352 base: OP_S390_STKARG "0" {
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;
361 base: OP_LDADDR (OP_S390_LOADARG) "0" {
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;
370 base: OP_LDADDR (OP_S390_ARGPTR) "0" {
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;
379 base: OP_LDADDR (OP_S390_STKARG) "0" {
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;
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;
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;
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;
413 reg: CEE_LDOBJ (OP_S390_LOADARG) "1" {
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;
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;
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;
439 base: CEE_LDOBJ (OP_S390_ARGPTR) "0" {
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;
449 base: CEE_LDOBJ (OP_S390_STKARG) "0" {
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;