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->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->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);
246 tmpr = mono_regstate_next_int (s->rs);
247 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
249 mini_emit_memcpy (s, s->frame_reg, soffset, tmpr,
250 tree->sreg1, size, 0);
254 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
255 /* nothing to do: the value is already on the FP stack */
258 stmt: CEE_BNE_UN (fpcflags) {
259 tree->opcode = OP_FBNE_UN;
260 mono_bblock_add_inst (s->cbb, tree);
263 stmt: CEE_BEQ (fpcflags) {
264 tree->opcode = OP_FBEQ;
265 mono_bblock_add_inst (s->cbb, tree);
268 stmt: CEE_BLT (fpcflags) {
269 tree->opcode = OP_FBLT;
270 mono_bblock_add_inst (s->cbb, tree);
273 stmt: CEE_BLT_UN (fpcflags) {
274 tree->opcode = OP_FBLT_UN;
275 mono_bblock_add_inst (s->cbb, tree);
278 stmt: CEE_BGT (fpcflags) {
279 tree->opcode = OP_FBGT;
280 mono_bblock_add_inst (s->cbb, tree);
283 stmt: CEE_BGT_UN (fpcflags) {
284 tree->opcode = OP_FBGT_UN;
285 mono_bblock_add_inst (s->cbb, tree);
288 stmt: CEE_BGE (fpcflags) {
289 tree->opcode = OP_FBGE;
290 mono_bblock_add_inst (s->cbb, tree);
293 stmt: CEE_BGE_UN (fpcflags) {
294 tree->opcode = OP_FBGE_UN;
295 mono_bblock_add_inst (s->cbb, tree);
298 stmt: CEE_BLE (fpcflags) {
299 tree->opcode = OP_FBLE;
300 mono_bblock_add_inst (s->cbb, tree);
303 stmt: CEE_BLE_UN (fpcflags) {
304 tree->opcode = OP_FBLE_UN;
305 mono_bblock_add_inst (s->cbb, tree);
308 stmt: CEE_POP (freg) "0" {
312 freg: OP_LCONV_TO_R8 (lreg) {
313 /* nothing to do - emulated */
316 freg: OP_LCONV_TO_R4 (lreg) {
317 /* nothing to do - emulated */
320 freg: OP_LCONV_TO_R_UN (lreg) {
321 /* nothing to do - emulated */
324 freg: OP_FREM (freg, freg) {
325 /* nothing to do - emulated */
328 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
329 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
330 state->left->right->reg1);
333 reg: OP_CLT (OP_COMPARE (freg, freg)) {
334 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
335 state->left->right->reg1);
338 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
339 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
340 state->left->right->reg1);
343 reg: OP_CGT (OP_COMPARE (freg, freg)) {
344 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
345 state->left->right->reg1);
348 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
349 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
350 state->left->right->reg1);
353 base: OP_REGOFFSET "0" {
356 base: OP_S390_STKARG "0" {
358 tmpr = mono_regstate_next_int (s->rs);
359 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
360 (s->stack_offset+state->tree->unused));
361 tree->inst_offset = state->tree->inst_offset;
362 tree->inst_basereg = tmpr;
365 base: OP_LDADDR (OP_S390_LOADARG) "0" {
367 tmpr = mono_regstate_next_int (s->rs);
368 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg,
369 state->left->tree->inst_offset);
370 tree->inst_offset = 0;
371 tree->inst_basereg = tmpr;
374 base: OP_LDADDR (OP_S390_ARGPTR) "0" {
376 tmpr = mono_regstate_next_int (s->rs);
377 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
378 state->left->tree->inst_offset);
379 tree->inst_offset = 0;
380 tree->inst_basereg = tmpr;
383 base: OP_LDADDR (OP_S390_STKARG) "0" {
385 tmpr = mono_regstate_next_int (s->rs);
386 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
387 (s->stack_offset + state->left->tree->unused));
388 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, tmpr,
389 state->left->tree->inst_offset);
390 tree->inst_offset = 0;
391 tree->inst_basereg = tmpr;
394 reg: OP_LDADDR (OP_S390_LOADARG) "2" {
395 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
396 state->left->tree->inst_offset);
397 tree->inst_offset = 0;
398 tree->inst_basereg = state->reg1;
401 reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
402 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
403 state->left->tree->inst_offset);
404 tree->inst_offset = 0;
405 tree->inst_basereg = state->reg1;
408 reg: OP_LDADDR (OP_S390_STKARG) "2" {
409 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
410 (s->stack_offset + state->left->tree->unused));
411 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
412 state->left->tree->inst_offset);
413 tree->inst_offset = 0;
414 tree->inst_basereg = state->reg1;
417 reg: CEE_LDOBJ (OP_S390_LOADARG) "1" {
419 tmpr = mono_regstate_next_int (s->rs);
420 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg,
421 state->left->tree->inst_offset);
422 tree->inst_offset = 0;
423 tree->inst_basereg = tmpr;
426 reg: CEE_LDOBJ (OP_S390_ARGPTR) "1" {
427 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
428 state->left->tree->inst_offset);
429 tree->inst_offset = 0;
430 tree->inst_basereg = state->reg1;
433 reg: CEE_LDOBJ (OP_S390_STKARG) "1" {
434 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
435 (s->stack_offset + state->left->tree->unused));
436 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
437 state->left->tree->inst_offset);
438 tree->inst_offset = 0;
439 tree->inst_basereg = state->reg1;
442 base: CEE_LDOBJ (OP_S390_ARGPTR) "0" {
444 tmpr = mono_regstate_next_int (s->rs);
445 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg,
446 state->left->tree->inst_offset);
447 tree->inst_offset = 0;
448 tree->inst_basereg = tmpr;
451 base: CEE_LDOBJ (OP_S390_STKARG) "0" {
453 tmpr = mono_regstate_next_int (s->rs);
454 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
455 (s->stack_offset + state->left->tree->unused));
456 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, tmpr, state->left->tree->inst_offset);
457 tree->inst_offset = 0;
458 tree->inst_basereg = tmpr;