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, sparc_o0, state->right->reg2);
16 MONO_EMIT_NEW_UNALU (s, OP_MOVE, sparc_o1, 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 mono_bblock_add_inst (s->cbb, tree);
32 freg: OP_LCONV_TO_R4 (lreg) {
33 mono_bblock_add_inst (s->cbb, tree);
36 freg: CEE_CONV_R_UN (reg) {
37 mono_bblock_add_inst (s->cbb, tree);
40 reg: OP_LOCALLOC (OP_ICONST) {
41 /* microcoded in mini-sparc.c */
42 tree->sreg1 = mono_regstate_next_int (s->rs);
43 MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
44 mono_bblock_add_inst (s->cbb, tree);
47 reg: OP_LOCALLOC (reg) {
48 mono_bblock_add_inst (s->cbb, tree);
51 base: OP_SPARC_INARG_VT (base) {
52 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->tree->inst_basereg,
53 state->left->tree->inst_offset);
56 reg: OP_LDADDR (OP_SPARC_INARG_VT (base)) {
57 MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->tree->inst_basereg,
58 state->left->left->tree->inst_offset);
61 base: OP_LDADDR (reg) {
63 tree->inst_basereg = mono_regstate_next_int (s->rs);
64 tree->inst_offset = 0;
66 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->inst_basereg, state->left->tree->dreg, 0);
68 tree->inst_basereg = state->left->tree->dreg;
69 tree->inst_offset = 0;
72 stmt: OP_OUTARG (OP_LDADDR (reg)) {
73 tree->opcode = OP_SETREG;
74 tree->dreg = tree->unused;
75 tree->sreg1 = state->left->left->tree->dreg;
76 mono_bblock_add_inst (s->cbb, tree);
79 stmt: OP_SETRET (reg) {
80 tree->opcode = OP_MOVE;
81 tree->sreg1 = state->left->reg1;
82 tree->dreg = sparc_i0;
83 mono_bblock_add_inst (s->cbb, tree);
86 stmt: OP_SETRET (lreg) {
87 MONO_EMIT_NEW_UNALU (s, OP_MOVE, sparc_i0, state->left->reg2);
88 tree->opcode = OP_MOVE;
89 tree->sreg1 = state->left->reg1;
90 tree->dreg = sparc_i1;
91 mono_bblock_add_inst (s->cbb, tree);
94 stmt: OP_SETRET (freg) {
95 MONO_EMIT_UNALU (s, tree, OP_FMOVE, sparc_f0, state->left->reg1);
96 mono_bblock_add_inst (s->cbb, tree);
99 stmt: OP_SETRET (OP_ICONST) {
100 tree->opcode = OP_ICONST;
101 tree->inst_c0 = state->left->tree->inst_c0;
102 tree->dreg = sparc_i0;
103 mono_bblock_add_inst (s->cbb, tree);
106 stmt: OP_OUTARG (reg) {
107 tree->opcode = OP_SETREG;
108 tree->dreg = tree->unused;
109 tree->sreg1 = state->left->reg1;
110 mono_bblock_add_inst (s->cbb, tree);
113 stmt: OP_OUTARG (OP_REGVAR) {
114 tree->opcode = OP_SETREG;
115 tree->dreg = tree->unused;
116 tree->sreg1 = state->left->tree->dreg;
117 mono_bblock_add_inst (s->cbb, tree);
120 stmt: OP_OUTARG (freg) {
121 /* floating-point <-> integer transfer must go through memory */
122 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
123 tree->inst_imm, state->left->reg1);
124 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
127 stmt: OP_OUTARG (OP_ICONST) {
128 tree->opcode = OP_SETREGIMM;
129 tree->dreg = tree->unused;
130 tree->inst_c0 = state->left->tree->inst_c0;
131 mono_bblock_add_inst (s->cbb, tree);
134 stmt: OP_OUTARG (CEE_LDIND_R4 (base)) {
135 tree->opcode = OP_LOADI4_MEMBASE;
136 tree->dreg = tree->unused;
137 tree->inst_basereg = state->left->left->tree->inst_basereg;
138 tree->inst_offset = state->left->left->tree->inst_offset;
139 mono_bblock_add_inst (s->cbb, tree);
142 stmt: OP_SPARC_OUTARG_REGPAIR (lreg) {
143 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
144 tree->opcode = OP_SETREG;
145 tree->dreg = tree->unused + 1;
146 tree->sreg1 = state->left->reg1;
147 mono_bblock_add_inst (s->cbb, tree);
150 stmt: OP_SPARC_OUTARG_REGPAIR (freg) {
151 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
152 tree->inst_imm, state->left->reg1);
153 /* floating-point <-> integer transfer must go through memory */
154 /* Load into a register pair */
155 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
156 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused + 1, tree->inst_basereg, tree->inst_imm + 4);
159 stmt: OP_SPARC_OUTARG_MEM (reg) {
160 if (tree->inst_imm & 0x1)
161 tree->opcode = OP_STOREI1_MEMBASE_REG;
162 else if (tree->inst_imm & 0x2)
163 tree->opcode = OP_STOREI2_MEMBASE_REG;
165 tree->opcode = OP_STOREI4_MEMBASE_REG;
166 tree->inst_destbasereg = tree->inst_basereg;
167 tree->inst_offset = tree->inst_imm;
168 tree->sreg1 = state->left->reg1;
169 mono_bblock_add_inst (s->cbb, tree);
172 stmt: OP_SPARC_OUTARG_MEM (freg) {
173 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
174 tree->inst_imm, state->left->reg1);
177 stmt: OP_SPARC_OUTARG_MEMPAIR (lreg) {
178 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, tree->inst_basereg,
179 tree->inst_imm, state->left->reg2);
180 tree->opcode = OP_STOREI4_MEMBASE_REG;
181 tree->inst_destbasereg = tree->inst_basereg;
182 tree->inst_offset = tree->inst_imm + 4;
183 tree->sreg1 = state->left->reg1;
184 mono_bblock_add_inst (s->cbb, tree);
187 stmt: OP_SPARC_OUTARG_MEMPAIR (freg) {
188 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
189 tree->inst_imm, state->left->reg1);
192 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (lreg) {
193 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
194 tree->opcode = OP_STOREI4_MEMBASE_REG;
195 tree->inst_destbasereg = tree->inst_basereg;
196 tree->inst_offset = tree->inst_imm + 4;
197 tree->sreg1 = state->left->reg1;
198 mono_bblock_add_inst (s->cbb, tree);
201 stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (freg) {
202 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
203 tree->inst_imm, state->left->reg1);
204 /* floating-point <-> integer transfer must go through memory */
205 /* Load most significant word into register */
206 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
209 # Handles scalar valuetypes like RuntimeTypeHandle
210 reg: OP_OUTARG_VT (OP_ICONST) {
211 int size = tree->unused;
212 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, sparc_sp, tree->inst_c1, state->left->tree->inst_c0);
213 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
216 reg: OP_OUTARG_VT (base) {
217 int size = tree->unused;
218 mini_emit_memcpy (s, sparc_sp, tree->inst_c1, state->left->tree->inst_basereg, state->left->tree->inst_offset, size, 0);
219 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
222 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
223 tree->opcode = OP_SETREG;
224 tree->sreg1 = state->left->left->tree->dreg;
225 tree->dreg = tree->unused;
226 mono_bblock_add_inst (s->cbb, tree);
229 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGOFFSET)) {
230 MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, state->left->left->tree->inst_basereg,
231 state->left->left->tree->inst_offset);
234 stmt: OP_OUTARG_VT (OP_ICONST) {
235 tree->opcode = OP_SETREGIMM;
236 tree->dreg = tree->unused;
237 tree->inst_imm = state->left->tree->inst_c0;
238 mono_bblock_add_inst (s->cbb, tree);
241 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
242 /* nothing to do: the value is already on the FP stack */
245 reg: CEE_LDIND_I2 (OP_REGVAR) {
246 /* All regs are 32 bit */
247 tree->opcode = OP_MOVE;
248 tree->sreg1 = state->left->tree->dreg;
249 tree->dreg = state->reg1;
250 mono_bblock_add_inst (s->cbb, tree);
253 stmt: CEE_BNE_UN (fpcflags) {
254 tree->opcode = OP_FBNE_UN;
255 mono_bblock_add_inst (s->cbb, tree);
258 stmt: CEE_BEQ (fpcflags) {
259 tree->opcode = OP_FBEQ;
260 mono_bblock_add_inst (s->cbb, tree);
263 stmt: CEE_BLT (fpcflags) {
264 tree->opcode = OP_FBLT;
265 mono_bblock_add_inst (s->cbb, tree);
268 stmt: CEE_BLT_UN (fpcflags) {
269 tree->opcode = OP_FBLT_UN;
270 mono_bblock_add_inst (s->cbb, tree);
273 stmt: CEE_BGT (fpcflags) {
274 tree->opcode = OP_FBGT;
275 mono_bblock_add_inst (s->cbb, tree);
278 stmt: CEE_BGT_UN (fpcflags) {
279 tree->opcode = OP_FBGT_UN;
280 mono_bblock_add_inst (s->cbb, tree);
283 stmt: CEE_BGE (fpcflags) {
284 tree->opcode = OP_FBGE;
285 mono_bblock_add_inst (s->cbb, tree);
288 stmt: CEE_BGE_UN (fpcflags) {
289 tree->opcode = OP_FBGE_UN;
290 mono_bblock_add_inst (s->cbb, tree);
293 stmt: CEE_BLE (fpcflags) {
294 tree->opcode = OP_FBLE;
295 mono_bblock_add_inst (s->cbb, tree);
298 stmt: CEE_BLE_UN (fpcflags) {
299 tree->opcode = OP_FBLE_UN;
300 mono_bblock_add_inst (s->cbb, tree);
303 stmt: CEE_POP (freg) "0" {
307 stmt: OP_START_HANDLER {
310 stmt: CEE_ENDFINALLY {
313 stmt: OP_ENDFILTER (reg) {
316 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
317 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
318 state->left->right->reg1);
321 reg: OP_CLT (OP_COMPARE (freg, freg)) {
322 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
323 state->left->right->reg1);
326 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
327 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
328 state->left->right->reg1);
331 reg: OP_CGT (OP_COMPARE (freg, freg)) {
332 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
333 state->left->right->reg1);
336 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
337 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
338 state->left->right->reg1);
345 stmt: OP_SETRET (CEE_LDIND_REF(base)) {
346 MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
347 state->left->left->tree->inst_offset);
348 mono_bblock_add_inst (s->cbb, tree);
351 stmt: OP_SETRET (CEE_LDIND_I4(base)) {
352 MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
353 state->left->left->tree->inst_offset);
354 mono_bblock_add_inst (s->cbb, tree);
357 stmt: OP_SETRET (CEE_LDIND_I(base)) {
358 MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
359 state->left->left->tree->inst_offset);
360 mono_bblock_add_inst (s->cbb, tree);
363 stmt: OP_OUTARG (CEE_LDIND_I (OP_REGVAR)) {
364 tree->opcode = OP_SETREG;
365 tree->dreg = tree->unused;
366 tree->sreg1 = state->left->left->tree->dreg;
367 mono_bblock_add_inst (s->cbb, tree);
370 stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)) {
371 tree->opcode = OP_SETREG;
372 tree->dreg = tree->unused;
373 tree->sreg1 = state->left->left->tree->dreg;
374 mono_bblock_add_inst (s->cbb, tree);
377 reg: OP_LDADDR (OP_REGOFFSET) "1" {
378 if (state->left->tree->inst_offset) {
379 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->tree->inst_basereg, state->left->tree->inst_offset);
381 tree->opcode = OP_MOVE;
382 tree->sreg1 = state->left->tree->inst_basereg;
383 tree->dreg = state->reg1;
385 mono_bblock_add_inst (s->cbb, tree);
388 stmt: OP_MEMSET (reg) "0" {
389 int size = tree->unused;
391 int destreg = state->left->reg1;
394 if (tree->inst_imm) {
395 val_reg = mono_regstate_next_int (s->rs);
396 MONO_EMIT_NEW_ICONST (s, val_reg, tree->inst_imm);
401 if ((tree->inst_imm == 0) && (size >= 8)) {
402 MONO_EMIT_NEW_ICONST (s, sparc_g1, 0);
405 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
412 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
417 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
422 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);