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, 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);
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);
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);
34 freg: OP_LCONV_TO_R4 (lreg) {
35 tree->sreg1 = state->left->reg1;
36 tree->dreg = state->reg1;
37 mono_bblock_add_inst (s->cbb, tree);
40 freg: CEE_CONV_R_UN (reg) {
41 tree->sreg1 = state->left->reg1;
42 tree->dreg = state->reg1;
43 mono_bblock_add_inst (s->cbb, tree);
46 reg: OP_LOCALLOC (OP_ICONST) {
47 /* microcoded in mini-sparc.c */
48 tree->sreg1 = mono_regstate_next_int (s->rs);
49 MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
50 mono_bblock_add_inst (s->cbb, tree);
53 reg: OP_LOCALLOC (reg) {
54 tree->sreg1 = state->left->reg1;
55 tree->dreg = state->reg1;
56 mono_bblock_add_inst (s->cbb, tree);
59 base: OP_SPARC_INARG_VT (base) {
60 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->tree->inst_basereg,
61 state->left->tree->inst_offset);
64 reg: OP_LDADDR (OP_SPARC_INARG_VT (base)) {
65 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->tree->inst_basereg,
66 state->left->left->tree->inst_offset);
69 reg: CEE_LDOBJ (OP_SPARC_INARG_VT (base)) {
70 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->tree->inst_basereg,
71 state->left->left->tree->inst_offset);
74 base: OP_LDADDR (reg) {
76 tree->inst_basereg = mono_regstate_next_int (s->rs);
77 tree->inst_offset = 0;
79 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->inst_basereg, state->left->tree->dreg, 0);
81 tree->inst_basereg = state->left->tree->dreg;
82 tree->inst_offset = 0;
85 stmt: OP_OUTARG (OP_LDADDR (reg)) {
86 tree->opcode = OP_SETREG;
87 tree->dreg = tree->unused;
88 tree->sreg1 = state->left->left->tree->dreg;
89 mono_bblock_add_inst (s->cbb, tree);
92 stmt: OP_SETRET (reg) {
93 tree->opcode = OP_MOVE;
94 tree->sreg1 = state->left->reg1;
95 tree->dreg = sparc_i0;
96 mono_bblock_add_inst (s->cbb, tree);
99 stmt: OP_SETRET (lreg) {
100 MONO_EMIT_NEW_UNALU (s, OP_MOVE, sparc_i0, state->left->reg2);
101 tree->opcode = OP_MOVE;
102 tree->sreg1 = state->left->reg1;
103 tree->dreg = sparc_i1;
104 mono_bblock_add_inst (s->cbb, tree);
107 stmt: OP_SETRET (freg) {
108 MONO_EMIT_UNALU (s, tree, OP_FMOVE, sparc_f0, state->left->reg1);
109 mono_bblock_add_inst (s->cbb, tree);
112 stmt: OP_SETRET (OP_ICONST) {
113 tree->opcode = OP_ICONST;
114 tree->inst_c0 = state->left->tree->inst_c0;
115 tree->dreg = sparc_i0;
116 mono_bblock_add_inst (s->cbb, tree);
119 stmt: OP_OUTARG (reg) {
120 tree->opcode = OP_SETREG;
121 tree->dreg = tree->unused;
122 tree->sreg1 = state->left->reg1;
123 mono_bblock_add_inst (s->cbb, tree);
126 stmt: OP_OUTARG (OP_REGVAR) {
127 tree->opcode = OP_SETREG;
128 tree->dreg = tree->unused;
129 tree->sreg1 = state->left->tree->dreg;
130 mono_bblock_add_inst (s->cbb, tree);
133 stmt: OP_OUTARG (freg) {
134 /* floating-point <-> integer transfer must go through memory */
135 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
136 tree->inst_imm, state->left->reg1);
137 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
140 stmt: OP_OUTARG (OP_ICONST) {
141 tree->opcode = OP_SETREGIMM;
142 tree->dreg = tree->unused;
143 tree->inst_c0 = state->left->tree->inst_c0;
144 mono_bblock_add_inst (s->cbb, tree);
147 stmt: OP_OUTARG (CEE_LDIND_R4 (base)) {
148 tree->opcode = OP_LOADI4_MEMBASE;
149 tree->dreg = tree->unused;
150 tree->inst_basereg = state->left->left->tree->inst_basereg;
151 tree->inst_offset = state->left->left->tree->inst_offset;
152 mono_bblock_add_inst (s->cbb, tree);
155 stmt: OP_SPARC_OUTARG_REGPAIR (lreg) {
156 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
157 tree->opcode = OP_SETREG;
158 tree->dreg = tree->unused + 1;
159 tree->sreg1 = state->left->reg1;
160 mono_bblock_add_inst (s->cbb, tree);
163 stmt: OP_SPARC_OUTARG_REGPAIR (freg) {
164 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
165 tree->inst_imm, state->left->reg1);
166 /* floating-point <-> integer transfer must go through memory */
167 /* Load into a register pair */
168 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
169 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused + 1, tree->inst_basereg, tree->inst_imm + 4);
172 stmt: OP_SPARC_OUTARG_MEM (reg) {
173 if (tree->inst_imm & 0x1)
174 tree->opcode = OP_STOREI1_MEMBASE_REG;
175 else if (tree->inst_imm & 0x2)
176 tree->opcode = OP_STOREI2_MEMBASE_REG;
178 tree->opcode = OP_STOREI4_MEMBASE_REG;
179 tree->inst_destbasereg = tree->inst_basereg;
180 tree->inst_offset = tree->inst_imm;
181 tree->sreg1 = state->left->reg1;
182 mono_bblock_add_inst (s->cbb, tree);
185 stmt: OP_SPARC_OUTARG_MEM (freg) {
186 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
187 tree->inst_imm, state->left->reg1);
190 stmt: OP_SPARC_OUTARG_MEMPAIR (lreg) {
191 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, tree->inst_basereg,
192 tree->inst_imm, state->left->reg2);
193 tree->opcode = OP_STOREI4_MEMBASE_REG;
194 tree->inst_destbasereg = tree->inst_basereg;
195 tree->inst_offset = tree->inst_imm + 4;
196 tree->sreg1 = state->left->reg1;
197 mono_bblock_add_inst (s->cbb, tree);
200 stmt: OP_SPARC_OUTARG_MEMPAIR (freg) {
201 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
202 tree->inst_imm, state->left->reg1);
205 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (lreg) {
206 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
207 tree->opcode = OP_STOREI4_MEMBASE_REG;
208 tree->inst_destbasereg = tree->inst_basereg;
209 tree->inst_offset = tree->inst_imm + 4;
210 tree->sreg1 = state->left->reg1;
211 mono_bblock_add_inst (s->cbb, tree);
214 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (freg) {
215 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
216 tree->inst_imm, state->left->reg1);
217 /* floating-point <-> integer transfer must go through memory */
218 /* Load most significant word into register */
219 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
222 # Handles scalar valuetypes like RuntimeTypeHandle
223 reg: OP_OUTARG_VT (OP_ICONST) {
224 int size = tree->unused;
225 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, sparc_sp, tree->inst_c1, state->left->tree->inst_c0);
226 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
229 reg: OP_OUTARG_VT (base) {
230 int size = tree->unused;
231 mini_emit_memcpy (s, sparc_sp, tree->inst_c1, state->left->tree->inst_basereg, state->left->tree->inst_offset, size, 0);
232 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
235 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
236 tree->opcode = OP_SETREG;
237 tree->sreg1 = state->left->left->tree->dreg;
238 tree->dreg = tree->unused;
239 mono_bblock_add_inst (s->cbb, tree);
242 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGOFFSET)) {
243 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, state->left->left->tree->inst_basereg,
244 state->left->left->tree->inst_offset);
247 stmt: OP_OUTARG_VT (OP_ICONST) {
248 tree->opcode = OP_SETREGIMM;
249 tree->dreg = tree->unused;
250 tree->inst_imm = state->left->tree->inst_c0;
251 mono_bblock_add_inst (s->cbb, tree);
254 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
255 /* nothing to do: the value is already on the FP stack */
258 reg: CEE_LDIND_I1 (OP_REGVAR) {
259 /* All regs are 32 bit */
260 tree->opcode = OP_MOVE;
261 tree->sreg1 = state->left->tree->dreg;
262 tree->dreg = state->reg1;
263 mono_bblock_add_inst (s->cbb, tree);
266 reg: CEE_LDIND_I2 (OP_REGVAR) {
267 /* All regs are 32 bit */
268 tree->opcode = OP_MOVE;
269 tree->sreg1 = state->left->tree->dreg;
270 tree->dreg = state->reg1;
271 mono_bblock_add_inst (s->cbb, tree);
274 stmt: CEE_BNE_UN (fpcflags) {
275 tree->opcode = OP_FBNE_UN;
276 mono_bblock_add_inst (s->cbb, tree);
279 stmt: CEE_BEQ (fpcflags) {
280 tree->opcode = OP_FBEQ;
281 mono_bblock_add_inst (s->cbb, tree);
284 stmt: CEE_BLT (fpcflags) {
285 tree->opcode = OP_FBLT;
286 mono_bblock_add_inst (s->cbb, tree);
289 stmt: CEE_BLT_UN (fpcflags) {
290 tree->opcode = OP_FBLT_UN;
291 mono_bblock_add_inst (s->cbb, tree);
294 stmt: CEE_BGT (fpcflags) {
295 tree->opcode = OP_FBGT;
296 mono_bblock_add_inst (s->cbb, tree);
299 stmt: CEE_BGT_UN (fpcflags) {
300 tree->opcode = OP_FBGT_UN;
301 mono_bblock_add_inst (s->cbb, tree);
304 stmt: CEE_BGE (fpcflags) {
305 tree->opcode = OP_FBGE;
306 mono_bblock_add_inst (s->cbb, tree);
309 stmt: CEE_BGE_UN (fpcflags) {
310 tree->opcode = OP_FBGE_UN;
311 mono_bblock_add_inst (s->cbb, tree);
314 stmt: CEE_BLE (fpcflags) {
315 tree->opcode = OP_FBLE;
316 mono_bblock_add_inst (s->cbb, tree);
319 stmt: CEE_BLE_UN (fpcflags) {
320 tree->opcode = OP_FBLE_UN;
321 mono_bblock_add_inst (s->cbb, tree);
324 stmt: CEE_POP (freg) "0" {
328 stmt: OP_START_HANDLER {
331 stmt: CEE_ENDFINALLY {
334 stmt: OP_ENDFILTER (reg) {
337 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
338 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
339 state->left->right->reg1);
342 reg: OP_CLT (OP_COMPARE (freg, freg)) {
343 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
344 state->left->right->reg1);
347 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
348 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
349 state->left->right->reg1);
352 reg: OP_CGT (OP_COMPARE (freg, freg)) {
353 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
354 state->left->right->reg1);
357 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
358 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
359 state->left->right->reg1);
366 stmt: OP_SETRET (CEE_LDIND_REF(base)) {
367 MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
368 state->left->left->tree->inst_offset);
369 mono_bblock_add_inst (s->cbb, tree);
372 stmt: OP_SETRET (CEE_LDIND_I4(base)) {
373 MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
374 state->left->left->tree->inst_offset);
375 mono_bblock_add_inst (s->cbb, tree);
378 stmt: OP_SETRET (CEE_LDIND_I(base)) {
379 MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
380 state->left->left->tree->inst_offset);
381 mono_bblock_add_inst (s->cbb, tree);
384 stmt: OP_OUTARG (CEE_LDIND_I (OP_REGVAR)) {
385 tree->opcode = OP_SETREG;
386 tree->dreg = tree->unused;
387 tree->sreg1 = state->left->left->tree->dreg;
388 mono_bblock_add_inst (s->cbb, tree);
391 stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)) {
392 tree->opcode = OP_SETREG;
393 tree->dreg = tree->unused;
394 tree->sreg1 = state->left->left->tree->dreg;
395 mono_bblock_add_inst (s->cbb, tree);
398 reg: OP_LDADDR (OP_REGOFFSET) "1" {
399 if (state->left->tree->inst_offset) {
400 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->tree->inst_basereg, state->left->tree->inst_offset);
402 tree->opcode = OP_MOVE;
403 tree->sreg1 = state->left->tree->inst_basereg;
404 tree->dreg = state->reg1;
406 mono_bblock_add_inst (s->cbb, tree);
409 # FIXME: This rule was commented out in inssel.brg, why ?
410 reg: CEE_REM (reg, OP_ICONST) {
411 MONO_EMIT_BIALU_IMM (s, tree, OP_REM_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
414 stmt: OP_MEMSET (reg) "0" {
415 int size = tree->unused;
417 int destreg = state->left->reg1;
420 if (tree->inst_imm) {
421 val_reg = mono_regstate_next_int (s->rs);
422 MONO_EMIT_NEW_ICONST (s, val_reg, tree->inst_imm);
427 /* FIXME: This assumes the destination is dword aligned */
429 if ((tree->inst_imm == 0) && (size >= 8)) {
430 MONO_EMIT_NEW_ICONST (s, sparc_g1, 0);
433 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
441 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
446 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
451 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);