4 # inssel-ppc.brg: burg file for special ppc instructions
7 # Dietmar Maurer (dietmar@ximian.com)
8 # Paolo Molaro (lupus@ximian.com)
10 # (C) 2002 Ximian, Inc.
13 stmt: OP_START_HANDLER {
14 MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
15 /*MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, spvar->inst_basereg, spvar->inst_offset, ppc_sp);
17 tree->inst_left = spvar;
18 mono_bblock_add_inst (s->cbb, tree);
21 stmt: CEE_ENDFINALLY {
22 MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
23 tree->inst_left = spvar;
24 mono_bblock_add_inst (s->cbb, tree);
27 stmt: OP_ENDFILTER (reg) {
28 MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
29 tree->inst_left = spvar;
30 tree->sreg1 = state->left->reg1;
31 mono_bblock_add_inst (s->cbb, tree);
34 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
35 /* this should only happen for methods returning a long */
36 MONO_EMIT_NEW_UNALU (s, OP_MOVE, ppc_r3, state->right->reg1);
37 MONO_EMIT_NEW_UNALU (s, OP_MOVE, ppc_r4, state->right->reg2);
40 lreg: OP_LNEG (lreg) "2" {
41 MONO_EMIT_NEW_BIALU_IMM (s, OP_PPC_SUBFIC, state->reg1, state->left->reg1, 0);
42 MONO_EMIT_UNALU (s, tree, OP_PPC_SUBFZE, state->reg2, state->left->reg2);
45 freg: OP_LCONV_TO_R8 (lreg) {
46 tree->dreg = state->reg1;
47 tree->sreg1 = state->left->reg1;
48 tree->sreg2 = state->left->reg2;
49 mono_bblock_add_inst (s->cbb, tree);
52 freg: OP_LCONV_TO_R4 (lreg) {
53 tree->dreg = state->reg1;
54 tree->sreg1 = state->left->reg1;
55 tree->sreg2 = state->left->reg2;
56 mono_bblock_add_inst (s->cbb, tree);
59 freg: CEE_CONV_R_UN (reg) {
60 tree->dreg = state->reg1;
61 tree->sreg1 = state->left->reg1;
62 mono_bblock_add_inst (s->cbb, tree);
65 reg: OP_LOCALLOC (OP_ICONST) {
66 /* microcoded in mini-ppc.c */
67 tree->sreg1 = mono_regstate_next_int (s->rs);
68 tree->dreg = state->reg1;
69 MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
70 mono_bblock_add_inst (s->cbb, tree);
73 reg: OP_LOCALLOC (reg) {
74 tree->dreg = state->reg1;
75 tree->sreg1 = state->left->reg1;
76 mono_bblock_add_inst (s->cbb, tree);
79 stmt: OP_SETRET (reg) {
80 tree->opcode = OP_MOVE;
81 tree->sreg1 = state->left->reg1;
83 mono_bblock_add_inst (s->cbb, tree);
86 stmt: OP_SETRET (lreg) {
87 tree->opcode = OP_SETLRET;
88 tree->sreg1 = state->left->reg1;
89 tree->sreg2 = state->left->reg2;
91 mono_bblock_add_inst (s->cbb, tree);
94 stmt: OP_SETRET (freg) {
95 tree->opcode = OP_FMOVE;
96 tree->sreg1 = state->left->reg1;
98 mono_bblock_add_inst (s->cbb, tree);
101 stmt: OP_SETRET (OP_ICONST) {
102 tree->opcode = OP_ICONST;
103 tree->inst_c0 = state->left->tree->inst_c0;
105 mono_bblock_add_inst (s->cbb, tree);
108 stmt: OP_OUTARG (reg) {
109 if (tree->inst_imm) {
110 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
113 tree->opcode = OP_SETREG;
114 tree->dreg = tree->unused;
115 tree->sreg1 = state->left->reg1;
116 mono_bblock_add_inst (s->cbb, tree);
119 stmt: OP_OUTARG (OP_REGVAR) {
120 if (tree->inst_imm) {
121 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->tree->dreg);
124 tree->opcode = OP_SETREG;
125 tree->dreg = tree->unused;
126 tree->sreg1 = state->left->tree->dreg;
127 mono_bblock_add_inst (s->cbb, tree);
130 stmt: OP_OUTARG (lreg) {
131 if (tree->inst_imm) {
132 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg2);
133 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm + 4, state->left->reg1);
136 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
137 tree->opcode = OP_SETREG;
138 tree->dreg = tree->unused + 1;
139 tree->sreg1 = state->left->reg1;
140 mono_bblock_add_inst (s->cbb, tree);
143 stmt: OP_OUTARG (OP_ICONST) {
144 if (tree->inst_imm) {
145 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, s->frame_reg, tree->inst_imm, state->left->tree->inst_c0);
148 tree->opcode = OP_SETREGIMM;
149 tree->dreg = tree->unused;
150 tree->inst_c0 = state->left->tree->inst_c0;
151 mono_bblock_add_inst (s->cbb, tree);
154 #stmt: OP_OUTARG (CEE_LDIND_I4 (base)) {
155 # tree->opcode = OP_X86_PUSH_MEMBASE;
156 # tree->inst_basereg = state->left->left->tree->inst_basereg;
157 # tree->inst_offset = state->left->left->tree->inst_offset;
158 # mono_bblock_add_inst (s->cbb, tree);
161 #stmt: OP_OUTARG (CEE_LDIND_U4 (base)) {
162 # tree->opcode = OP_X86_PUSH_MEMBASE;
163 # tree->inst_basereg = state->left->left->tree->inst_basereg;
164 # tree->inst_offset = state->left->left->tree->inst_offset;
165 # mono_bblock_add_inst (s->cbb, tree);
168 #stmt: OP_OUTARG (CEE_LDIND_I (base)) {
169 # tree->opcode = OP_X86_PUSH_MEMBASE;
170 # tree->inst_basereg = state->left->left->tree->inst_basereg;
171 # tree->inst_offset = state->left->left->tree->inst_offset;
172 # mono_bblock_add_inst (s->cbb, tree);
175 #stmt: OP_OUTARG (CEE_LDIND_REF (base)) {
176 # tree->opcode = OP_X86_PUSH_MEMBASE;
177 # tree->inst_basereg = state->left->left->tree->inst_basereg;
178 # tree->inst_offset = state->left->left->tree->inst_offset;
179 # mono_bblock_add_inst (s->cbb, tree);
182 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
183 if (tree->inst_imm) {
184 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->left->tree->dreg);
187 tree->opcode = OP_SETREG;
188 tree->sreg1 = state->left->left->tree->dreg;
189 tree->dreg = tree->unused;
190 mono_bblock_add_inst (s->cbb, tree);
193 #stmt: OP_OUTARG (CEE_LDOBJ (reg)) {
194 # tree->opcode = OP_X86_PUSH;
195 # tree->sreg1 = state->left->reg1;
196 # mono_bblock_add_inst (s->cbb, tree);
199 stmt: OP_OUTARG (freg) {
200 if (tree->inst_imm) {
201 int opcode = (tree->unused & 0xff00) == 0x0400? OP_STORER4_MEMBASE_REG: OP_STORER8_MEMBASE_REG;
202 MONO_EMIT_NEW_STORE_MEMBASE (s, opcode, s->frame_reg, tree->inst_imm, state->left->reg1);
205 tree->opcode = OP_SETFREG;
206 tree->sreg1 = state->left->reg1;
207 tree->dreg = tree->unused & 0xff;
208 mono_bblock_add_inst (s->cbb, tree);
211 stmt: OP_OUTARG_R4 (freg) {
212 if (tree->inst_imm) {
213 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
216 tree->opcode = OP_SETFREG;
217 tree->sreg1 = state->left->reg1;
218 tree->dreg = tree->unused;
219 mono_bblock_add_inst (s->cbb, tree);
222 stmt: OP_OUTARG_R8 (freg) {
223 if (tree->inst_imm) {
224 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
227 tree->opcode = OP_SETFREG;
228 tree->sreg1 = state->left->reg1;
229 tree->dreg = tree->unused;
230 mono_bblock_add_inst (s->cbb, tree);
233 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
234 MonoInst *vt = state->left->left->tree;
235 int start_reg = tree->unused & 0xff;
236 int nregs = (tree->unused >> 8) & 0xff;
237 int ovf_size = (tree->unused >> 16) & 0xffff;
238 int i, tmpr, soffset;
239 soffset = vt->inst_offset;
240 for (i = 0; i < nregs; ++i) {
241 tmpr = mono_regstate_next_int (s->rs);
242 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, vt->inst_basereg, soffset);
243 MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg + i, tmpr);
244 soffset += sizeof (gpointer);
246 //g_print ("vt size: %d at R%d + %d\n", tree->inst_imm, vt->inst_basereg, vt->inst_offset);
248 mini_emit_memcpy (s, s->frame_reg, tree->inst_imm + (soffset - vt->inst_offset), vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
252 stmt: OP_OUTARG_VT (OP_ICONST) {
253 int start_reg = tree->unused & 0xff;
254 int nregs = (tree->unused >> 8) & 0xff;
256 tree->opcode = OP_SETREGIMM;
257 tree->dreg = start_reg;
258 tree->inst_c0 = state->left->tree->inst_c0;
259 mono_bblock_add_inst (s->cbb, tree);
261 g_assert_not_reached ();
265 stmt: OP_OUTARG_VT (reg) {
266 int start_reg = tree->unused & 0xff;
267 int nregs = (tree->unused >> 8) & 0xff;
269 tree->opcode = OP_SETREG;
270 tree->dreg = start_reg;
271 tree->sreg1 = state->left->tree->dreg;
272 mono_bblock_add_inst (s->cbb, tree);
274 g_assert_not_reached ();
278 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
279 /* nothing to do: the value is already on the FP stack */
282 stmt: CEE_BNE_UN (fpcflags) {
283 tree->opcode = OP_FBNE_UN;
284 mono_bblock_add_inst (s->cbb, tree);
287 stmt: CEE_BEQ (fpcflags) {
288 tree->opcode = OP_FBEQ;
289 mono_bblock_add_inst (s->cbb, tree);
292 stmt: CEE_BLT (fpcflags) {
293 tree->opcode = OP_FBLT;
294 mono_bblock_add_inst (s->cbb, tree);
297 stmt: CEE_BLT_UN (fpcflags) {
298 tree->opcode = OP_FBLT_UN;
299 mono_bblock_add_inst (s->cbb, tree);
302 stmt: CEE_BGT (fpcflags) {
303 tree->opcode = OP_FBGT;
304 mono_bblock_add_inst (s->cbb, tree);
307 stmt: CEE_BGT_UN (fpcflags) {
308 tree->opcode = OP_FBGT_UN;
309 mono_bblock_add_inst (s->cbb, tree);
312 stmt: CEE_BGE (fpcflags) {
313 tree->opcode = OP_FBGE;
314 mono_bblock_add_inst (s->cbb, tree);
317 stmt: CEE_BGE_UN (fpcflags) {
318 tree->opcode = OP_FBGE_UN;
319 mono_bblock_add_inst (s->cbb, tree);
322 stmt: CEE_BLE (fpcflags) {
323 tree->opcode = OP_FBLE;
324 mono_bblock_add_inst (s->cbb, tree);
327 stmt: CEE_BLE_UN (fpcflags) {
328 tree->opcode = OP_FBLE_UN;
329 mono_bblock_add_inst (s->cbb, tree);
332 stmt: CEE_POP (freg) "0" {
336 freg: OP_LCONV_TO_R8 (lreg) {
337 /* nothing to do - emulated */
340 freg: OP_LCONV_TO_R4 (lreg) {
341 /* nothing to do - emulated */
344 freg: OP_LCONV_TO_R_UN (lreg) {
345 /* nothing to do - emulated */
348 freg: OP_FREM (freg, freg) {
349 /* nothing to do - emulated */
352 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
353 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
354 state->left->right->reg1);
357 reg: OP_CLT (OP_COMPARE (freg, freg)) {
358 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
359 state->left->right->reg1);
362 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
363 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
364 state->left->right->reg1);
367 reg: OP_CGT (OP_COMPARE (freg, freg)) {
368 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
369 state->left->right->reg1);
372 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
373 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
374 state->left->right->reg1);
377 reg: CEE_ADD_OVF (reg, reg) "0" {
378 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);