Remove docs from mono-1-0 branch
[mono.git] / mono / mini / inssel-sparc.brg
1 %%
2
3 #
4 # inssel-sparc.brg: burg file for special sparc instructions
5 #
6 # Author:
7 #   Dietmar Maurer (dietmar@ximian.com)
8 #   Paolo Molaro (lupus@ximian.com)
9 #
10 # (C) 2002 Ximian, Inc.
11 #
12
13 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
14         /* this should only happen for methods returning a long */
15         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->left->tree->dreg, state->right->reg2);
16         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->left->tree->dreg + 1, state->right->reg1);
17 }
18
19 lreg: CEE_LDIND_I8 (OP_REGVAR) {
20         /* reg2 contains the most significant word */
21         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg2, state->left->tree->dreg);
22         tree->opcode = OP_SETREG;
23         tree->dreg = state->reg1;
24         tree->sreg1 = state->left->tree->dreg + 1;
25         mono_bblock_add_inst (s->cbb, tree);
26 }
27
28 freg: OP_LCONV_TO_R8 (lreg) {
29         tree->sreg1 = state->left->reg1;
30         tree->dreg = state->reg1;
31         mono_bblock_add_inst (s->cbb, tree);
32 }
33
34 freg: OP_LCONV_TO_R8 (lreg) {
35         /* Dummy rule */
36 }
37
38 freg: OP_LCONV_TO_R4 (lreg) {
39         tree->sreg1 = state->left->reg1;
40         tree->dreg = state->reg1;
41         mono_bblock_add_inst (s->cbb, tree);
42 }
43
44 freg: CEE_CONV_R_UN (reg) {
45         tree->sreg1 = state->left->reg1;
46         tree->dreg = state->reg1;
47         mono_bblock_add_inst (s->cbb, tree);
48 }
49
50 freg: OP_FCONV_TO_R4 (freg) "0" {
51         /* The conversion is done elsewhere */
52         MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->reg1);
53 }
54
55 reg: OP_LOCALLOC (reg) {
56         tree->sreg1 = state->left->reg1;
57         tree->dreg = state->reg1;
58         mono_bblock_add_inst (s->cbb, tree);
59 }
60
61 base: OP_SPARC_INARG_VT (base) {
62         MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->tree->inst_basereg, 
63                                         state->left->tree->inst_offset);
64 }
65
66 reg: OP_LDADDR (OP_SPARC_INARG_VT (base)) {
67         MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->tree->inst_basereg, 
68                                         state->left->left->tree->inst_offset);
69 }
70
71 reg: CEE_LDOBJ (OP_SPARC_INARG_VT (base)) {
72         MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->tree->inst_basereg, 
73                                         state->left->left->tree->inst_offset);
74 }
75
76 base: OP_LDADDR (reg) {
77 /*
78         tree->inst_basereg = mono_regstate_next_int (s->rs);
79         tree->inst_offset = 0;
80
81         MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->inst_basereg, state->left->tree->dreg, 0);
82 */
83         tree->inst_basereg = state->left->tree->dreg;
84         tree->inst_offset = 0;
85 }
86
87 stmt: OP_OUTARG (OP_LDADDR (reg)) {
88         tree->opcode = OP_SETREG;
89         tree->dreg = tree->unused;
90         tree->sreg1 = state->left->left->tree->dreg;
91         mono_bblock_add_inst (s->cbb, tree);
92 }
93
94 stmt: OP_SETRET (reg) {
95         tree->opcode = OP_MOVE;
96         tree->sreg1 = state->left->reg1;
97         tree->dreg = sparc_i0;
98         mono_bblock_add_inst (s->cbb, tree);
99 }
100
101 stmt: OP_SETRET (lreg) {
102         MONO_EMIT_NEW_UNALU (s, OP_MOVE, sparc_i0, state->left->reg2);
103         tree->opcode = OP_MOVE;
104         tree->sreg1 = state->left->reg1;
105         tree->dreg = sparc_i1;
106         mono_bblock_add_inst (s->cbb, tree);
107 }
108
109 stmt: OP_SETRET (freg) {
110         tree->opcode = OP_SETFRET;
111         tree->sreg1 = state->left->reg1;
112         tree->dreg = sparc_f0;
113         mono_bblock_add_inst (s->cbb, tree);
114 }
115
116 stmt: OP_SETRET (OP_ICONST) {
117         tree->opcode = OP_ICONST;
118         tree->inst_c0 = state->left->tree->inst_c0;
119         tree->dreg = sparc_i0;
120         mono_bblock_add_inst (s->cbb, tree);
121 }
122
123 stmt: OP_OUTARG (reg) {
124         tree->opcode = OP_SETREG;
125         tree->dreg = tree->unused;
126         tree->sreg1 = state->left->reg1;
127         mono_bblock_add_inst (s->cbb, tree);
128 }
129
130 stmt: OP_OUTARG (OP_REGVAR) {
131         tree->opcode = OP_SETREG;
132         tree->dreg = tree->unused;
133         tree->sreg1 = state->left->tree->dreg;
134         mono_bblock_add_inst (s->cbb, tree);
135 }
136
137 stmt: OP_OUTARG (freg) {
138         /* floating-point <-> integer transfer must go through memory */
139         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
140                                                                 tree->inst_imm, state->left->reg1);
141         MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
142 }
143
144 stmt: OP_OUTARG (OP_ICONST) {
145         tree->opcode = OP_SETREGIMM;
146         tree->dreg = tree->unused;
147         tree->inst_c0 = state->left->tree->inst_c0;
148         mono_bblock_add_inst (s->cbb, tree);
149 }
150
151 stmt: OP_OUTARG (CEE_LDIND_R4 (base)) {
152         tree->opcode = OP_LOADI4_MEMBASE;
153         tree->dreg = tree->unused;
154         tree->inst_basereg = state->left->left->tree->inst_basereg;
155         tree->inst_offset = state->left->left->tree->inst_offset;
156         mono_bblock_add_inst (s->cbb, tree);
157 }
158
159 stmt: OP_SPARC_OUTARG_REGPAIR (lreg) {
160         MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
161         tree->opcode = OP_SETREG;
162         tree->dreg = tree->unused + 1;
163         tree->sreg1 = state->left->reg1;
164         mono_bblock_add_inst (s->cbb, tree);
165 }
166
167 stmt: OP_SPARC_OUTARG_REGPAIR (freg) {
168         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
169                                                                 tree->inst_imm, state->left->reg1);
170         /* floating-point <-> integer transfer must go through memory */
171         /* Load into a register pair */
172         MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
173         MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused + 1, tree->inst_basereg, tree->inst_imm + 4);
174 }
175
176 stmt: OP_SPARC_OUTARG_MEM (reg) {
177         if (tree->inst_imm & 0x1)
178                 tree->opcode = OP_STOREI1_MEMBASE_REG;
179         else if (tree->inst_imm & 0x2)
180                 tree->opcode = OP_STOREI2_MEMBASE_REG;
181         else
182                 tree->opcode = OP_STOREI4_MEMBASE_REG;
183         tree->inst_destbasereg = tree->inst_basereg;
184         tree->inst_offset = tree->inst_imm;
185         tree->sreg1 = state->left->reg1;
186         mono_bblock_add_inst (s->cbb, tree);
187 }
188
189 stmt: OP_SPARC_OUTARG_MEM (freg) {
190         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
191                                                                 tree->inst_imm, state->left->reg1);
192 }
193
194 stmt: OP_SPARC_OUTARG_MEMPAIR (lreg) {
195         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, tree->inst_basereg,
196                                                                 tree->inst_imm, state->left->reg2);
197         tree->opcode = OP_STOREI4_MEMBASE_REG;
198         tree->inst_destbasereg = tree->inst_basereg;
199         tree->inst_offset = tree->inst_imm + 4;
200         tree->sreg1 = state->left->reg1;
201         mono_bblock_add_inst (s->cbb, tree);
202 }
203
204 stmt: OP_SPARC_OUTARG_MEMPAIR (freg) {
205         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
206                                                                 tree->inst_imm, state->left->reg1);
207 }
208
209 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (lreg) {
210         MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
211         tree->opcode = OP_STOREI4_MEMBASE_REG;
212         tree->inst_destbasereg = tree->inst_basereg;
213         tree->inst_offset = tree->inst_imm + 4;
214         tree->sreg1 = state->left->reg1;
215         mono_bblock_add_inst (s->cbb, tree);
216 }
217
218 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (freg) {
219         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
220                                                                 tree->inst_imm, state->left->reg1);
221         /* floating-point <-> integer transfer must go through memory */
222         /* Load most significant word into register */
223         MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
224 }
225
226 # Handles scalar valuetypes like RuntimeTypeHandle
227 reg: OP_OUTARG_VT (OP_ICONST) {
228         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, sparc_sp, tree->inst_c1, state->left->tree->inst_c0);
229         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
230 }
231
232 reg: OP_OUTARG_VT (OP_AOTCONST) {
233         MONO_EMIT_NEW_AOTCONST (s, state->reg1, state->left->tree->inst_p0, state->left->tree->inst_c1);
234         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, sparc_sp, tree->inst_c1, state->reg1);
235         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
236 }
237
238 # FIXME: Unify this with the previous rule
239 reg: OP_OUTARG_VT (OP_REFANYTYPE (reg)) {
240         MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->reg1, G_STRUCT_OFFSET (MonoTypedRef, type));
241         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, sparc_sp, tree->inst_c1, state->reg1);
242         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
243 }       
244
245 reg: OP_OUTARG_VT (base) {
246         int size = tree->unused;
247         mini_emit_memcpy (s, sparc_sp, tree->inst_c1, state->left->tree->inst_basereg, state->left->tree->inst_offset, size, 0);
248         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
249 }
250
251 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
252         tree->opcode = OP_SETREG;
253         tree->sreg1 = state->left->left->tree->dreg;
254         tree->dreg = tree->unused;
255         mono_bblock_add_inst (s->cbb, tree);
256 }
257
258 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGOFFSET)) {
259         MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, state->left->left->tree->inst_basereg, 
260                                                                 state->left->left->tree->inst_offset);
261 }
262
263 stmt: OP_OUTARG_VT (OP_ICONST) {
264         tree->opcode = OP_SETREGIMM;
265         tree->dreg = tree->unused;
266         tree->inst_imm = state->left->tree->inst_c0;
267         mono_bblock_add_inst (s->cbb, tree);
268 }
269
270 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
271         /* nothing to do: the value is already on the FP stack */
272 }
273
274 reg: CEE_LDIND_I1 (OP_REGVAR) {
275         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->tree->dreg);
276 }
277
278 reg: CEE_LDIND_I2 (OP_REGVAR) {
279         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->tree->dreg);
280 }
281
282 stmt: CEE_BNE_UN (fpcflags) {
283         tree->opcode = OP_FBNE_UN;
284         mono_bblock_add_inst (s->cbb, tree);
285 }
286
287 stmt: CEE_BEQ (fpcflags) {
288         tree->opcode = OP_FBEQ;
289         mono_bblock_add_inst (s->cbb, tree);
290 }
291
292 stmt: CEE_BLT (fpcflags) {
293         tree->opcode = OP_FBLT;
294         mono_bblock_add_inst (s->cbb, tree);
295 }
296
297 stmt: CEE_BLT_UN (fpcflags) {
298         tree->opcode = OP_FBLT_UN;
299         mono_bblock_add_inst (s->cbb, tree);
300 }
301
302 stmt: CEE_BGT (fpcflags) {
303         tree->opcode = OP_FBGT;
304         mono_bblock_add_inst (s->cbb, tree);
305 }
306
307 stmt: CEE_BGT_UN (fpcflags) {
308         tree->opcode = OP_FBGT_UN;
309         mono_bblock_add_inst (s->cbb, tree);
310 }
311
312 stmt: CEE_BGE  (fpcflags) {
313         tree->opcode = OP_FBGE;
314         mono_bblock_add_inst (s->cbb, tree);
315 }
316
317 stmt: CEE_BGE_UN (fpcflags) {
318         tree->opcode = OP_FBGE_UN;
319         mono_bblock_add_inst (s->cbb, tree);
320 }
321
322 stmt: CEE_BLE  (fpcflags) {
323         tree->opcode = OP_FBLE;
324         mono_bblock_add_inst (s->cbb, tree);
325 }
326
327 stmt: CEE_BLE_UN (fpcflags) {
328         tree->opcode = OP_FBLE_UN;
329         mono_bblock_add_inst (s->cbb, tree);
330 }
331
332 stmt: CEE_POP (freg) "0" {
333         /* nothing to do */
334 }     
335
336 stmt: OP_START_HANDLER {
337      mono_bblock_add_inst (s->cbb, tree);
338 }
339
340 stmt: CEE_ENDFINALLY {
341         //MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
342         //MONO_EMIT_NEW_LOAD_MEMBASE (s, sparc_o7, spvar->inst_basereg, spvar->inst_offset); 
343         mono_bblock_add_inst (s->cbb, tree);
344 }
345
346 stmt: OP_ENDFILTER (reg) {
347         //MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
348         //MONO_EMIT_NEW_LOAD_MEMBASE (s, sparc_o7, spvar->inst_basereg, spvar->inst_offset); 
349         tree->sreg1 = state->left->reg1;
350         mono_bblock_add_inst (s->cbb, tree);
351 }
352
353 stmt: OP_START_HANDLER {
354 }
355
356 stmt: CEE_ENDFINALLY {
357         mono_bblock_add_inst (s->cbb, tree);
358 }
359
360 stmt: OP_ENDFILTER (reg) {
361         tree->sreg1 = state->left->reg1;
362         tree->dreg = state->reg1;
363         mono_bblock_add_inst (s->cbb, tree);
364 }
365
366 reg: OP_CEQ (OP_COMPARE (freg, freg)) { 
367         MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
368                          state->left->right->reg1);
369 }
370
371 reg: OP_CLT (OP_COMPARE (freg, freg)) { 
372         MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
373                          state->left->right->reg1);
374 }
375
376 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {      
377         MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
378                          state->left->right->reg1);
379 }
380
381 reg: OP_CGT (OP_COMPARE (freg, freg)) { 
382         MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
383                          state->left->right->reg1);
384 }
385
386 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {      
387         MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
388                          state->left->right->reg1);
389 }
390
391 reg: OP_LOCALLOC (reg) {
392         tree->sreg1 = state->left->tree->dreg;
393         mono_bblock_add_inst (s->cbb, tree);
394 }
395
396 #
397 # Optimizations
398 #
399
400 stmt: CEE_STIND_I1 (OP_REGVAR, OP_ICONST) {
401         tree->opcode = OP_ICONST;
402         tree->dreg = state->left->tree->dreg;
403         tree->inst_c0 = state->right->tree->inst_c0;
404         mono_bblock_add_inst (s->cbb, tree);
405 }
406
407 stmt: CEE_STIND_I2 (OP_REGVAR, OP_ICONST) {
408         tree->opcode = OP_ICONST;
409         tree->dreg = state->left->tree->dreg;
410         tree->inst_c0 = state->right->tree->inst_c0;
411         mono_bblock_add_inst (s->cbb, tree);
412 }
413
414 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (reg, OP_ICONST)) {
415         MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
416 }
417
418 stmt: CEE_STIND_REF (OP_REGVAR, CEE_ADD (reg, OP_ICONST)) {
419         MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
420 }
421
422 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_SUB (reg, OP_ICONST)) {
423         MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
424 }
425
426 stmt: CEE_STIND_REF (OP_REGVAR, CEE_SUB (reg, OP_ICONST)) {
427         MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
428 }
429
430 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (reg, reg)) {
431         MONO_EMIT_BIALU (s, tree, CEE_ADD, state->left->tree->dreg, state->right->left->reg1, state->right->right->reg1);
432 }
433
434 stmt: CEE_STIND_REF (OP_REGVAR, CEE_ADD (reg, reg)) {
435         MONO_EMIT_BIALU (s, tree, CEE_ADD, state->left->tree->dreg, state->right->left->reg1, state->right->right->reg1);
436 }
437
438 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4(base)) {
439         MONO_EMIT_LOAD_MEMBASE (s, tree, state->left->tree->dreg, state->right->left->tree->inst_basereg, 
440                                 state->right->left->tree->inst_offset); 
441         mono_bblock_add_inst (s->cbb, tree);
442 }
443
444 stmt: CEE_STIND_REF (OP_REGVAR, CEE_LDIND_REF(base)) {
445         MONO_EMIT_LOAD_MEMBASE (s, tree, state->left->tree->dreg, state->right->left->tree->inst_basereg, 
446                                 state->right->left->tree->inst_offset); 
447         mono_bblock_add_inst (s->cbb, tree);
448 }
449
450 stmt: OP_SETRET (CEE_LDIND_REF(base)) {
451         MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg, 
452                                 state->left->left->tree->inst_offset);  
453         mono_bblock_add_inst (s->cbb, tree);
454 }
455
456 stmt: OP_SETRET (CEE_LDIND_I4(base)) {
457         MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg, 
458                                 state->left->left->tree->inst_offset);  
459         mono_bblock_add_inst (s->cbb, tree);
460 }
461
462 stmt: OP_SETRET (CEE_LDIND_I(base)) {
463         MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg, 
464                                 state->left->left->tree->inst_offset);  
465         mono_bblock_add_inst (s->cbb, tree);
466 }
467
468 stmt: OP_SETRET (CEE_LDIND_I4(OP_REGVAR)) {
469         tree->opcode = OP_SETREG;
470         tree->dreg = sparc_i0;
471         tree->sreg1 = state->left->left->tree->dreg;
472         mono_bblock_add_inst (s->cbb, tree);
473 }
474
475 stmt: OP_SETRET (CEE_LDIND_I(OP_REGVAR)) {
476         tree->opcode = OP_SETREG;
477         tree->dreg = sparc_i0;
478         tree->sreg1 = state->left->left->tree->dreg;
479         mono_bblock_add_inst (s->cbb, tree);
480 }
481
482 stmt: OP_OUTARG (CEE_LDIND_I (OP_REGVAR)) {
483         tree->opcode = OP_SETREG;
484         tree->dreg = tree->unused;
485         tree->sreg1 = state->left->left->tree->dreg;
486         mono_bblock_add_inst (s->cbb, tree);
487 }
488
489 stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)) {
490         tree->opcode = OP_SETREG;
491         tree->dreg = tree->unused;
492         tree->sreg1 = state->left->left->tree->dreg;
493         mono_bblock_add_inst (s->cbb, tree);
494 }
495
496 stmt: OP_OUTARG (CEE_LDIND_REF(base)) {
497         MONO_EMIT_LOAD_MEMBASE (s, tree, tree->unused, state->left->left->tree->inst_basereg, 
498                                 state->left->left->tree->inst_offset);  
499         mono_bblock_add_inst (s->cbb, tree);
500 }
501
502 stmt: OP_OUTARG (CEE_LDIND_I4(base)) {
503         MONO_EMIT_LOAD_MEMBASE (s, tree, tree->unused, state->left->left->tree->inst_basereg, 
504                                 state->left->left->tree->inst_offset);  
505         mono_bblock_add_inst (s->cbb, tree);
506 }
507
508 reg: OP_LDADDR (OP_REGOFFSET) "1" {
509         if (state->left->tree->inst_offset) {
510                 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->tree->inst_basereg, state->left->tree->inst_offset);
511         } else {
512                 tree->opcode = OP_MOVE;
513                 tree->sreg1 = state->left->tree->inst_basereg;
514                 tree->dreg = state->reg1;
515         }
516         mono_bblock_add_inst (s->cbb, tree);
517 }
518
519 # FIXME: This rule was commented out in inssel.brg, why ?
520 reg: CEE_REM (reg, OP_ICONST) {
521         MONO_EMIT_BIALU_IMM (s, tree, OP_REM_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
522 }
523
524 # This one too
525 reg: CEE_DIV (reg, OP_ICONST) {
526         MONO_EMIT_BIALU_IMM (s, tree, OP_DIV_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
527 }
528
529 reg: OP_LOCALLOC (OP_ICONST) {
530         tree->opcode = OP_SPARC_LOCALLOC_IMM;
531         tree->inst_c0 = state->left->tree->inst_c0;
532         tree->dreg = state->reg1;
533         mono_bblock_add_inst (s->cbb, tree);
534 }
535
536 # Optimized version for initializing valuetypes on the stack
537 stmt: OP_MEMSET (OP_LDADDR(OP_REGOFFSET)) "0" {
538         int size = tree->unused;
539         int offset = state->left->left->tree->inst_offset;
540         int destreg = state->left->left->tree->inst_basereg;
541         int val_reg;
542
543         if (tree->inst_imm) {
544                 val_reg = mono_regstate_next_int (s->rs);
545                 MONO_EMIT_NEW_ICONST (s, val_reg, tree->inst_imm);
546         }
547         else
548                 val_reg = sparc_g0;
549
550         /* Target address must be dword aligned */
551         if ((tree->inst_imm == 0) && (size >= 8) && 
552                 (destreg == sparc_fp) && ((offset % 8) == 0)) {
553                 if (!mono_sparc_is_v9 ()) {
554                         /* Use STD */
555                         MONO_EMIT_NEW_ICONST (s, sparc_g1, 0);
556
557                         while (size >= 8) {
558                                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
559                                 offset += 8;
560                                 size -= 8;
561                         }
562                 }
563                 else {
564                         /* Use STX imm */
565                         while (size >= 8) {
566                                 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI8_MEMBASE_IMM, destreg, offset, 0);
567                                 offset += 8;
568                                 size -= 8;
569                         }
570                 }
571         }
572                 
573         while (size >= 4) {
574                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
575                 offset += 4;
576                 size -= 4;
577         }
578         while (size >= 2) {
579                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
580                 offset += 2;
581                 size -= 2;
582         }
583         while (size >= 1) {
584                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
585                 offset += 1;
586                 size -= 1;
587         }
588 }               
589
590 stmt: OP_MEMSET (reg) "0" {
591         int size = tree->unused;
592         int offset = 0;
593         int destreg = state->left->reg1;
594         int val_reg;
595
596         if (tree->inst_imm) {
597                 val_reg = mono_regstate_next_int (s->rs);
598                 MONO_EMIT_NEW_ICONST (s, val_reg, tree->inst_imm);
599         }
600         else
601                 val_reg = sparc_g0;
602
603         /* FIXME: This assumes the destination is dword aligned */
604         /*
605         if ((tree->inst_imm == 0) && (size >= 8)) {
606                 while (size >= 8) {
607                         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_IMM, destreg, offset, sparc_g0);
608                         offset += 8;
609                         size -= 8;
610                 }
611         }
612         */
613                 
614         while (size >= 4) {
615                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
616                 offset += 4;
617                 size -= 4;
618         }
619         while (size >= 2) {
620                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
621                 offset += 2;
622                 size -= 2;
623         }
624         while (size >= 1) {
625                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
626                 offset += 1;
627                 size -= 1;
628         }
629 }
630
631 %%