4 # inssel-sparc.brg: burg file for special sparc instructions
7 # Dietmar Maurer (dietmar@ximian.com)
8 # Paolo Molaro (lupus@ximian.com)
10 # (C) 2002 Ximian, Inc.
13 stmt: CEE_STIND_I8 (OP_REGVAR, reg) {
14 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->left->tree->dreg, state->right->reg1);
17 reg: CEE_LDIND_I8 (OP_REGVAR) {
18 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->tree->dreg);
21 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
22 /* this should only happen for methods returning a long */
23 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->left->tree->dreg, state->right->reg2);
24 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->left->tree->dreg + 1, state->right->reg1);
27 lreg: CEE_LDIND_I8 (OP_REGVAR) {
28 /* reg2 contains the most significant word */
29 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg2, state->left->tree->dreg);
30 tree->opcode = OP_SETREG;
31 tree->dreg = state->reg1;
32 tree->sreg1 = state->left->tree->dreg + 1;
33 mono_bblock_add_inst (s->cbb, tree);
36 freg: OP_LCONV_TO_R8 (lreg) {
37 tree->sreg1 = state->left->reg1;
38 tree->dreg = state->reg1;
39 mono_bblock_add_inst (s->cbb, tree);
42 freg: OP_LCONV_TO_R8 (lreg) {
46 freg: OP_LCONV_TO_R4 (lreg) {
47 tree->sreg1 = state->left->reg1;
48 tree->dreg = state->reg1;
49 mono_bblock_add_inst (s->cbb, tree);
52 freg: CEE_CONV_R_UN (reg) {
53 tree->sreg1 = state->left->reg1;
54 tree->dreg = state->reg1;
55 mono_bblock_add_inst (s->cbb, tree);
58 freg: OP_FCONV_TO_R4 (freg) "0" {
59 /* The conversion is done elsewhere */
60 MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->reg1);
63 freg: CEE_LDIND_R8 (OP_REGVAR) {
64 MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->tree->dreg);
67 freg: CEE_LDIND_R4 (OP_REGVAR) {
68 MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->tree->dreg);
71 reg: OP_LOCALLOC (reg) {
72 tree->sreg1 = state->left->reg1;
73 tree->dreg = state->reg1;
74 mono_bblock_add_inst (s->cbb, tree);
77 base: OP_SPARC_INARG_VT (base) {
78 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->tree->inst_basereg,
79 state->left->tree->inst_offset);
82 reg: OP_LDADDR (OP_SPARC_INARG_VT (base)) {
83 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->tree->inst_basereg,
84 state->left->left->tree->inst_offset);
87 reg: CEE_LDOBJ (OP_SPARC_INARG_VT (base)) {
88 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->tree->inst_basereg,
89 state->left->left->tree->inst_offset);
92 base: OP_LDADDR (reg) {
94 tree->inst_basereg = mono_regstate_next_int (s->rs);
95 tree->inst_offset = 0;
97 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->inst_basereg, state->left->tree->dreg, 0);
99 tree->inst_basereg = state->left->tree->dreg;
100 tree->inst_offset = 0;
103 stmt: OP_OUTARG (OP_LDADDR (reg)) {
104 tree->opcode = OP_SETREG;
105 tree->dreg = tree->unused;
106 tree->sreg1 = state->left->left->tree->dreg;
107 mono_bblock_add_inst (s->cbb, tree);
110 stmt: OP_SETRET (reg) {
111 tree->opcode = OP_MOVE;
112 tree->sreg1 = state->left->reg1;
113 tree->dreg = sparc_i0;
114 mono_bblock_add_inst (s->cbb, tree);
117 stmt: OP_SETRET (lreg) {
118 MONO_EMIT_NEW_UNALU (s, OP_MOVE, sparc_i0, state->left->reg2);
119 tree->opcode = OP_MOVE;
120 tree->sreg1 = state->left->reg1;
121 tree->dreg = sparc_i1;
122 mono_bblock_add_inst (s->cbb, tree);
125 stmt: OP_SETRET (freg) {
126 tree->opcode = OP_SETFRET;
127 tree->sreg1 = state->left->reg1;
128 tree->dreg = sparc_f0;
129 mono_bblock_add_inst (s->cbb, tree);
132 stmt: OP_SETRET (OP_ICONST) {
133 tree->opcode = OP_ICONST;
134 tree->inst_c0 = state->left->tree->inst_c0;
135 tree->dreg = sparc_i0;
136 mono_bblock_add_inst (s->cbb, tree);
139 stmt: OP_OUTARG (reg) {
140 tree->opcode = OP_SETREG;
141 tree->dreg = tree->unused;
142 tree->sreg1 = state->left->reg1;
143 mono_bblock_add_inst (s->cbb, tree);
146 stmt: OP_OUTARG (OP_REGVAR) {
147 tree->opcode = OP_SETREG;
148 tree->dreg = tree->unused;
149 tree->sreg1 = state->left->tree->dreg;
150 mono_bblock_add_inst (s->cbb, tree);
153 stmt: OP_OUTARG (freg) {
154 /* floating-point <-> integer transfer must go through memory */
155 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
156 tree->inst_imm, state->left->reg1);
157 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
160 stmt: OP_OUTARG (OP_ICONST) {
161 tree->opcode = OP_SETREGIMM;
162 tree->dreg = tree->unused;
163 tree->inst_c0 = state->left->tree->inst_c0;
164 mono_bblock_add_inst (s->cbb, tree);
167 stmt: OP_OUTARG (OP_I8CONST) {
168 tree->opcode = OP_SETREGIMM;
169 tree->dreg = tree->unused;
170 tree->inst_c0 = state->left->tree->inst_c0;
171 mono_bblock_add_inst (s->cbb, tree);
173 MBCOND (sizeof (gpointer) == 8);
178 stmt: OP_OUTARG (CEE_LDIND_R4 (base)) {
179 tree->opcode = OP_LOADI4_MEMBASE;
180 tree->dreg = tree->unused;
181 tree->inst_basereg = state->left->left->tree->inst_basereg;
182 tree->inst_offset = state->left->left->tree->inst_offset;
183 mono_bblock_add_inst (s->cbb, tree);
186 stmt: OP_SPARC_OUTARG_REGPAIR (lreg) {
187 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
188 tree->opcode = OP_SETREG;
189 tree->dreg = tree->unused + 1;
190 tree->sreg1 = state->left->reg1;
191 mono_bblock_add_inst (s->cbb, tree);
194 stmt: OP_SPARC_OUTARG_REGPAIR (freg) {
195 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
196 tree->inst_imm, state->left->reg1);
197 /* floating-point <-> integer transfer must go through memory */
198 /* Load into a register pair */
199 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
200 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused + 1, tree->inst_basereg, tree->inst_imm + 4);
203 stmt: OP_SPARC_OUTARG_MEM (reg) {
204 guint32 offset = tree->inst_imm;
205 if (mono_sparc_is_sparc64 ()) {
206 guint32 real_offset = tree->inst_imm - MONO_SPARC_STACK_BIAS;
207 /* Correct for the additions in get_call_info () */
208 offset = MONO_SPARC_STACK_BIAS + (real_offset & ~(7));
209 tree->opcode = OP_STOREI8_MEMBASE_REG;
212 if (tree->inst_imm & 0x1)
213 tree->opcode = OP_STOREI1_MEMBASE_REG;
214 else if (tree->inst_imm & 0x2)
215 tree->opcode = OP_STOREI2_MEMBASE_REG;
217 tree->opcode = OP_STOREI4_MEMBASE_REG;
219 tree->inst_destbasereg = tree->inst_basereg;
220 tree->inst_offset = offset;
221 tree->sreg1 = state->left->reg1;
222 mono_bblock_add_inst (s->cbb, tree);
225 stmt: OP_SPARC_OUTARG_MEM (freg) {
226 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
227 tree->inst_imm, state->left->reg1);
230 stmt: OP_SPARC_OUTARG_MEMPAIR (lreg) {
231 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, tree->inst_basereg,
232 tree->inst_imm, state->left->reg2);
233 tree->opcode = OP_STOREI4_MEMBASE_REG;
234 tree->inst_destbasereg = tree->inst_basereg;
235 tree->inst_offset = tree->inst_imm + 4;
236 tree->sreg1 = state->left->reg1;
237 mono_bblock_add_inst (s->cbb, tree);
240 stmt: OP_SPARC_OUTARG_MEMPAIR (freg) {
241 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
242 tree->inst_imm, state->left->reg1);
245 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (lreg) {
246 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
247 tree->opcode = OP_STOREI4_MEMBASE_REG;
248 tree->inst_destbasereg = tree->inst_basereg;
249 tree->inst_offset = tree->inst_imm + 4;
250 tree->sreg1 = state->left->reg1;
251 mono_bblock_add_inst (s->cbb, tree);
254 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (freg) {
255 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
256 tree->inst_imm, state->left->reg1);
257 /* floating-point <-> integer transfer must go through memory */
258 /* Load most significant word into register */
259 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
262 stmt: OP_SPARC_OUTARG_FLOAT_REG (freg) {
263 tree->opcode = OP_SPARC_SETFREG_FLOAT;
264 tree->dreg = tree->unused;
265 tree->sreg1 = state->left->reg1;
266 mono_bblock_add_inst (s->cbb, tree);
269 stmt: OP_SPARC_OUTARG_DOUBLE_REG (freg) {
270 tree->opcode = OP_SETFREG;
271 tree->dreg = tree->unused;
272 tree->sreg1 = state->left->reg1;
273 mono_bblock_add_inst (s->cbb, tree);
276 # Handles scalar valuetypes like RuntimeTypeHandle
277 reg: OP_OUTARG_VT (OP_ICONST) {
278 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, sparc_sp, tree->inst_c1, state->left->tree->inst_c0);
279 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
282 reg: OP_OUTARG_VT (OP_AOTCONST) {
283 MONO_EMIT_NEW_AOTCONST (s, state->reg1, state->left->tree->inst_p0, state->left->tree->inst_c1);
284 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, sparc_sp, tree->inst_c1, state->reg1);
285 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
288 # FIXME: Unify this with the previous rule
289 reg: OP_OUTARG_VT (OP_REFANYTYPE (reg)) {
290 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->reg1, G_STRUCT_OFFSET (MonoTypedRef, type));
291 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, sparc_sp, tree->inst_c1, state->reg1);
292 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
295 reg: OP_OUTARG_VT (base) {
296 int size = tree->unused;
297 mini_emit_memcpy (s, sparc_sp, tree->inst_c1, state->left->tree->inst_basereg, state->left->tree->inst_offset, size, 0);
298 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
301 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
302 tree->opcode = OP_SETREG;
303 tree->sreg1 = state->left->left->tree->dreg;
304 tree->dreg = tree->unused;
305 mono_bblock_add_inst (s->cbb, tree);
308 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGOFFSET)) {
309 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, state->left->left->tree->inst_basereg,
310 state->left->left->tree->inst_offset);
313 stmt: OP_OUTARG_VT (OP_ICONST) {
314 tree->opcode = OP_SETREGIMM;
315 tree->dreg = tree->unused;
316 tree->inst_imm = state->left->tree->inst_c0;
317 mono_bblock_add_inst (s->cbb, tree);
320 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
321 /* nothing to do: the value is already on the FP stack */
324 reg: CEE_LDIND_I1 (OP_REGVAR) {
325 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->tree->dreg);
328 reg: CEE_LDIND_I2 (OP_REGVAR) {
329 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->tree->dreg);
332 stmt: CEE_BNE_UN (fpcflags) {
333 tree->opcode = OP_FBNE_UN;
334 mono_bblock_add_inst (s->cbb, tree);
337 stmt: CEE_BEQ (fpcflags) {
338 tree->opcode = OP_FBEQ;
339 mono_bblock_add_inst (s->cbb, tree);
342 stmt: CEE_BLT (fpcflags) {
343 tree->opcode = OP_FBLT;
344 mono_bblock_add_inst (s->cbb, tree);
347 stmt: CEE_BLT_UN (fpcflags) {
348 tree->opcode = OP_FBLT_UN;
349 mono_bblock_add_inst (s->cbb, tree);
352 stmt: CEE_BGT (fpcflags) {
353 tree->opcode = OP_FBGT;
354 mono_bblock_add_inst (s->cbb, tree);
357 stmt: CEE_BGT_UN (fpcflags) {
358 tree->opcode = OP_FBGT_UN;
359 mono_bblock_add_inst (s->cbb, tree);
362 stmt: CEE_BGE (fpcflags) {
363 tree->opcode = OP_FBGE;
364 mono_bblock_add_inst (s->cbb, tree);
367 stmt: CEE_BGE_UN (fpcflags) {
368 tree->opcode = OP_FBGE_UN;
369 mono_bblock_add_inst (s->cbb, tree);
372 stmt: CEE_BLE (fpcflags) {
373 tree->opcode = OP_FBLE;
374 mono_bblock_add_inst (s->cbb, tree);
377 stmt: CEE_BLE_UN (fpcflags) {
378 tree->opcode = OP_FBLE_UN;
379 mono_bblock_add_inst (s->cbb, tree);
382 stmt: CEE_POP (freg) "0" {
386 stmt: OP_START_HANDLER {
387 mono_bblock_add_inst (s->cbb, tree);
390 stmt: CEE_ENDFINALLY {
391 //MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
392 //MONO_EMIT_NEW_LOAD_MEMBASE (s, sparc_o7, spvar->inst_basereg, spvar->inst_offset);
393 mono_bblock_add_inst (s->cbb, tree);
396 stmt: OP_ENDFILTER (reg) {
397 //MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
398 //MONO_EMIT_NEW_LOAD_MEMBASE (s, sparc_o7, spvar->inst_basereg, spvar->inst_offset);
399 tree->sreg1 = state->left->reg1;
400 mono_bblock_add_inst (s->cbb, tree);
403 stmt: OP_START_HANDLER {
406 stmt: CEE_ENDFINALLY {
407 mono_bblock_add_inst (s->cbb, tree);
410 stmt: OP_ENDFILTER (reg) {
411 tree->sreg1 = state->left->reg1;
412 tree->dreg = state->reg1;
413 mono_bblock_add_inst (s->cbb, tree);
416 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
417 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
418 state->left->right->reg1);
421 reg: OP_CLT (OP_COMPARE (freg, freg)) {
422 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
423 state->left->right->reg1);
426 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
427 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
428 state->left->right->reg1);
431 reg: OP_CGT (OP_COMPARE (freg, freg)) {
432 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
433 state->left->right->reg1);
436 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
437 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
438 state->left->right->reg1);
441 reg: OP_LOCALLOC (reg) {
442 tree->sreg1 = state->left->tree->dreg;
443 mono_bblock_add_inst (s->cbb, tree);
450 reg: CEE_LDIND_REF (OP_REGVAR),
451 reg: CEE_LDIND_I (OP_REGVAR),
452 reg: CEE_LDIND_I4 (OP_REGVAR),
453 reg: CEE_LDIND_U4 (OP_REGVAR) "0" {
454 /* This rule might not work on all archs, hence it is sparc only */
455 state->reg1 = state->left->tree->dreg;
456 tree->dreg = state->reg1;
459 stmt: CEE_STIND_I1 (OP_REGVAR, OP_ICONST) {
460 tree->opcode = OP_ICONST;
461 tree->dreg = state->left->tree->dreg;
462 tree->inst_c0 = state->right->tree->inst_c0;
463 mono_bblock_add_inst (s->cbb, tree);
466 stmt: CEE_STIND_I2 (OP_REGVAR, OP_ICONST) {
467 tree->opcode = OP_ICONST;
468 tree->dreg = state->left->tree->dreg;
469 tree->inst_c0 = state->right->tree->inst_c0;
470 mono_bblock_add_inst (s->cbb, tree);
473 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (reg, OP_ICONST)) {
474 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
477 stmt: CEE_STIND_REF (OP_REGVAR, CEE_ADD (reg, OP_ICONST)) {
478 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
481 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_SUB (reg, OP_ICONST)) {
482 MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
485 stmt: CEE_STIND_REF (OP_REGVAR, CEE_SUB (reg, OP_ICONST)) {
486 MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
489 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (reg, reg)) {
490 MONO_EMIT_BIALU (s, tree, CEE_ADD, state->left->tree->dreg, state->right->left->reg1, state->right->right->reg1);
493 stmt: CEE_STIND_REF (OP_REGVAR, CEE_ADD (reg, reg)) {
494 MONO_EMIT_BIALU (s, tree, CEE_ADD, state->left->tree->dreg, state->right->left->reg1, state->right->right->reg1);
497 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4(base)) {
498 MONO_EMIT_LOAD_MEMBASE (s, tree, state->left->tree->dreg, state->right->left->tree->inst_basereg,
499 state->right->left->tree->inst_offset);
500 mono_bblock_add_inst (s->cbb, tree);
503 stmt: CEE_STIND_REF (OP_REGVAR, CEE_LDIND_REF(base)) {
504 MONO_EMIT_LOAD_MEMBASE (s, tree, state->left->tree->dreg, state->right->left->tree->inst_basereg,
505 state->right->left->tree->inst_offset);
506 mono_bblock_add_inst (s->cbb, tree);
509 stmt: OP_SETRET (CEE_LDIND_I1(base)),
510 stmt: OP_SETRET (CEE_LDIND_U1(base)),
511 stmt: OP_SETRET (CEE_LDIND_I2(base)),
512 stmt: OP_SETRET (CEE_LDIND_U2(base)),
513 stmt: OP_SETRET (CEE_LDIND_I(base)),
514 stmt: OP_SETRET (CEE_LDIND_REF(base)),
515 stmt: OP_SETRET (CEE_LDIND_I4(base)),
516 stmt: OP_SETRET (CEE_LDIND_U4(base)) {
517 MONO_EMIT_LOAD_MEMBASE_OP (s, tree, ldind_to_load_membase (state->left->tree->opcode),
518 sparc_i0, state->left->left->tree->inst_basereg, state->left->left->tree->inst_offset);
519 mono_bblock_add_inst (s->cbb, tree);
522 stmt: OP_SETRET (CEE_LDIND_I4(OP_REGVAR)) {
523 tree->opcode = OP_SETREG;
524 tree->dreg = sparc_i0;
525 tree->sreg1 = state->left->left->tree->dreg;
526 mono_bblock_add_inst (s->cbb, tree);
529 stmt: OP_SETRET (CEE_LDIND_I(OP_REGVAR)) {
530 tree->opcode = OP_SETREG;
531 tree->dreg = sparc_i0;
532 tree->sreg1 = state->left->left->tree->dreg;
533 mono_bblock_add_inst (s->cbb, tree);
536 stmt: OP_OUTARG (CEE_LDIND_I (OP_REGVAR)) {
537 tree->opcode = OP_SETREG;
538 tree->dreg = tree->unused;
539 tree->sreg1 = state->left->left->tree->dreg;
540 mono_bblock_add_inst (s->cbb, tree);
543 stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)) {
544 tree->opcode = OP_SETREG;
545 tree->dreg = tree->unused;
546 tree->sreg1 = state->left->left->tree->dreg;
547 mono_bblock_add_inst (s->cbb, tree);
550 stmt: OP_OUTARG (CEE_LDIND_REF(base)) {
551 MONO_EMIT_LOAD_MEMBASE (s, tree, tree->unused, state->left->left->tree->inst_basereg,
552 state->left->left->tree->inst_offset);
553 mono_bblock_add_inst (s->cbb, tree);
556 stmt: OP_OUTARG (CEE_LDIND_I4(base)) {
557 MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, tree->unused, state->left->left->tree->inst_basereg,
558 state->left->left->tree->inst_offset);
559 mono_bblock_add_inst (s->cbb, tree);
562 reg: OP_LDADDR (OP_REGOFFSET) "1" {
563 if (state->left->tree->inst_offset) {
564 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->tree->inst_basereg, state->left->tree->inst_offset);
566 tree->opcode = OP_MOVE;
567 tree->sreg1 = state->left->tree->inst_basereg;
568 tree->dreg = state->reg1;
570 mono_bblock_add_inst (s->cbb, tree);
573 # FIXME: This rule was commented out in inssel.brg, why ?
574 reg: CEE_REM (reg, OP_ICONST) {
575 MONO_EMIT_BIALU_IMM (s, tree, OP_REM_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
579 reg: CEE_DIV (reg, OP_ICONST) {
580 MONO_EMIT_BIALU_IMM (s, tree, OP_DIV_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
583 reg: OP_LOCALLOC (OP_ICONST) {
584 tree->opcode = OP_SPARC_LOCALLOC_IMM;
585 tree->inst_c0 = state->left->tree->inst_c0;
586 tree->dreg = state->reg1;
587 mono_bblock_add_inst (s->cbb, tree);
590 # FIXME: Optimized MEMCPY for copying valuetypes
592 # Optimized version for initializing valuetypes on the stack
593 stmt: OP_MEMSET (OP_LDADDR(OP_REGOFFSET)) "0" {
594 int size = tree->unused;
595 int offset = state->left->left->tree->inst_offset;
596 int destreg = state->left->left->tree->inst_basereg;
599 if (tree->inst_imm) {
600 val_reg = mono_regstate_next_int (s->rs);
601 MONO_EMIT_NEW_ICONST (s, val_reg, tree->inst_imm);
606 /* Target address must be dword aligned */
607 if ((tree->inst_imm == 0) && (size >= 8) &&
608 (destreg == sparc_fp) && (((offset - MONO_SPARC_STACK_BIAS) % 8) == 0)) {
609 if (!mono_sparc_is_v9 ()) {
611 MONO_EMIT_NEW_ICONST (s, sparc_g1, 0);
614 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
622 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI8_MEMBASE_IMM, destreg, offset, 0);
630 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
635 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
640 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
646 stmt: OP_MEMSET (reg) "0" {
647 int size = tree->unused;
649 int destreg = state->left->reg1;
652 if (tree->inst_imm) {
653 val_reg = mono_regstate_next_int (s->rs);
654 MONO_EMIT_NEW_ICONST (s, val_reg, tree->inst_imm);
659 /* FIXME: This assumes the destination is dword aligned */
661 if ((tree->inst_imm == 0) && (size >= 8)) {
663 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_IMM, destreg, offset, sparc_g0);
671 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
676 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
681 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
688 stmt: CEE_STIND_R8 (base, OP_R8CONST) {
689 /* fp constants are pricy on SPARC */
690 guint64 d = *(guint64*)state->right->tree->inst_p0;
693 if (sizeof (gpointer) == 8) {
694 MONO_EMIT_STORE_MEMBASE (s, tree, OP_STOREI8_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset, sparc_g0);
697 /* STOREI8 would write %g1 as well */
698 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset, sparc_g0);
699 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset + 4, sparc_g0);
703 state->right->tree->dreg = state->reg1;
704 mono_bblock_add_inst (s->cbb, state->right->tree);
705 MONO_EMIT_STORE_MEMBASE (s, tree, OP_STORER8_MEMBASE_REG, state->left->tree->inst_basereg,
706 state->left->tree->inst_offset, state->reg1);