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 mono_bblock_add_inst (s->cbb, tree);
49 freg: OP_LCONV_TO_R4 (lreg) {
50 mono_bblock_add_inst (s->cbb, tree);
53 freg: CEE_CONV_R_UN (reg) {
54 mono_bblock_add_inst (s->cbb, tree);
57 reg: OP_LOCALLOC (OP_ICONST) {
58 /* microcoded in mini-ppc.c */
59 tree->sreg1 = mono_regstate_next_int (s->rs);
60 MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
61 mono_bblock_add_inst (s->cbb, tree);
64 reg: OP_LOCALLOC (reg) {
65 mono_bblock_add_inst (s->cbb, tree);
68 stmt: OP_SETRET (reg) {
69 tree->opcode = OP_MOVE;
70 tree->sreg1 = state->left->reg1;
72 mono_bblock_add_inst (s->cbb, tree);
75 stmt: OP_SETRET (lreg) {
76 tree->opcode = OP_SETLRET;
77 tree->sreg1 = state->left->reg1;
78 tree->sreg2 = state->left->reg2;
79 mono_bblock_add_inst (s->cbb, tree);
82 stmt: OP_SETRET (freg) {
83 tree->opcode = OP_FMOVE;
84 tree->sreg1 = state->left->reg1;
86 mono_bblock_add_inst (s->cbb, tree);
89 stmt: OP_SETRET (OP_ICONST) {
90 tree->opcode = OP_ICONST;
91 tree->inst_c0 = state->left->tree->inst_c0;
93 mono_bblock_add_inst (s->cbb, tree);
96 stmt: OP_OUTARG (reg) {
98 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
101 tree->opcode = OP_SETREG;
102 tree->dreg = tree->unused;
103 tree->sreg1 = state->left->reg1;
104 mono_bblock_add_inst (s->cbb, tree);
107 stmt: OP_OUTARG (OP_REGVAR) {
108 if (tree->inst_imm) {
109 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->tree->dreg);
112 tree->opcode = OP_SETREG;
113 tree->dreg = tree->unused;
114 tree->sreg1 = state->left->tree->dreg;
115 mono_bblock_add_inst (s->cbb, tree);
118 stmt: OP_OUTARG (lreg) {
119 if (tree->inst_imm) {
120 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg2);
121 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm + 4, state->left->reg1);
124 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
125 tree->opcode = OP_SETREG;
126 tree->dreg = tree->unused + 1;
127 tree->sreg1 = state->left->reg1;
128 mono_bblock_add_inst (s->cbb, tree);
131 stmt: OP_OUTARG (OP_ICONST) {
132 if (tree->inst_imm) {
133 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, s->frame_reg, tree->inst_imm, state->left->tree->inst_c0);
136 tree->opcode = OP_SETREGIMM;
137 tree->dreg = tree->unused;
138 tree->inst_c0 = state->left->tree->inst_c0;
139 mono_bblock_add_inst (s->cbb, tree);
142 #stmt: OP_OUTARG (CEE_LDIND_I4 (base)) {
143 # tree->opcode = OP_X86_PUSH_MEMBASE;
144 # tree->inst_basereg = state->left->left->tree->inst_basereg;
145 # tree->inst_offset = state->left->left->tree->inst_offset;
146 # mono_bblock_add_inst (s->cbb, tree);
149 #stmt: OP_OUTARG (CEE_LDIND_U4 (base)) {
150 # tree->opcode = OP_X86_PUSH_MEMBASE;
151 # tree->inst_basereg = state->left->left->tree->inst_basereg;
152 # tree->inst_offset = state->left->left->tree->inst_offset;
153 # mono_bblock_add_inst (s->cbb, tree);
156 #stmt: OP_OUTARG (CEE_LDIND_I (base)) {
157 # tree->opcode = OP_X86_PUSH_MEMBASE;
158 # tree->inst_basereg = state->left->left->tree->inst_basereg;
159 # tree->inst_offset = state->left->left->tree->inst_offset;
160 # mono_bblock_add_inst (s->cbb, tree);
163 #stmt: OP_OUTARG (CEE_LDIND_REF (base)) {
164 # tree->opcode = OP_X86_PUSH_MEMBASE;
165 # tree->inst_basereg = state->left->left->tree->inst_basereg;
166 # tree->inst_offset = state->left->left->tree->inst_offset;
167 # mono_bblock_add_inst (s->cbb, tree);
170 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
171 if (tree->inst_imm) {
172 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->left->tree->dreg);
175 tree->opcode = OP_SETREG;
176 tree->sreg1 = state->left->left->tree->dreg;
177 tree->dreg = tree->unused;
178 mono_bblock_add_inst (s->cbb, tree);
181 #stmt: OP_OUTARG (CEE_LDOBJ (reg)) {
182 # tree->opcode = OP_X86_PUSH;
183 # tree->sreg1 = state->left->reg1;
184 # mono_bblock_add_inst (s->cbb, tree);
187 stmt: OP_OUTARG (freg) {
188 if (tree->inst_imm) {
189 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
192 tree->opcode = OP_SETFREG;
193 tree->sreg1 = state->left->reg1;
194 tree->dreg = tree->unused;
195 mono_bblock_add_inst (s->cbb, tree);
198 stmt: OP_OUTARG_R4 (freg) {
199 if (tree->inst_imm) {
200 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
203 tree->opcode = OP_SETFREG;
204 tree->sreg1 = state->left->reg1;
205 tree->dreg = tree->unused;
206 mono_bblock_add_inst (s->cbb, tree);
209 stmt: OP_OUTARG_R8 (freg) {
210 if (tree->inst_imm) {
211 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
214 tree->opcode = OP_SETFREG;
215 tree->sreg1 = state->left->reg1;
216 tree->dreg = tree->unused;
217 mono_bblock_add_inst (s->cbb, tree);
220 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
221 MonoInst *vt = state->left->left->tree;
222 int start_reg = tree->unused & 0xff;
223 int nregs = (tree->unused >> 8) & 0xff;
224 int ovf_size = (tree->unused >> 16) & 0xffff;
225 int i, tmpr, soffset;
226 soffset = vt->inst_offset;
227 for (i = 0; i < nregs; ++i) {
228 tmpr = mono_regstate_next_int (s->rs);
229 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, vt->inst_basereg, soffset);
230 MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg + i, tmpr);
231 soffset += sizeof (gpointer);
233 //g_print ("vt size: %d at R%d + %d\n", tree->inst_imm, vt->inst_basereg, vt->inst_offset);
235 mini_emit_memcpy (s, s->frame_reg, tree->inst_imm + (soffset - vt->inst_offset), vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
239 stmt: OP_OUTARG_VT (OP_ICONST) {
240 int start_reg = tree->unused & 0xff;
241 int nregs = (tree->unused >> 8) & 0xff;
242 int ovf_size = (tree->unused >> 16) & 0xffff;
244 tree->opcode = OP_SETREGIMM;
245 tree->dreg = start_reg;
246 tree->inst_c0 = state->left->tree->inst_c0;
247 mono_bblock_add_inst (s->cbb, tree);
249 g_assert_not_reached ();
253 stmt: OP_OUTARG_VT (reg) {
254 int start_reg = tree->unused & 0xff;
255 int nregs = (tree->unused >> 8) & 0xff;
256 int ovf_size = (tree->unused >> 16) & 0xffff;
258 tree->opcode = OP_SETREG;
259 tree->dreg = start_reg;
260 tree->sreg1 = state->left->tree->dreg;
261 mono_bblock_add_inst (s->cbb, tree);
263 g_assert_not_reached ();
267 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
268 /* nothing to do: the value is already on the FP stack */
271 stmt: CEE_BNE_UN (fpcflags) {
272 tree->opcode = OP_FBNE_UN;
273 mono_bblock_add_inst (s->cbb, tree);
276 stmt: CEE_BEQ (fpcflags) {
277 tree->opcode = OP_FBEQ;
278 mono_bblock_add_inst (s->cbb, tree);
281 stmt: CEE_BLT (fpcflags) {
282 tree->opcode = OP_FBLT;
283 mono_bblock_add_inst (s->cbb, tree);
286 stmt: CEE_BLT_UN (fpcflags) {
287 tree->opcode = OP_FBLT_UN;
288 mono_bblock_add_inst (s->cbb, tree);
291 stmt: CEE_BGT (fpcflags) {
292 tree->opcode = OP_FBGT;
293 mono_bblock_add_inst (s->cbb, tree);
296 stmt: CEE_BGT_UN (fpcflags) {
297 tree->opcode = OP_FBGT_UN;
298 mono_bblock_add_inst (s->cbb, tree);
301 stmt: CEE_BGE (fpcflags) {
302 tree->opcode = OP_FBGE;
303 mono_bblock_add_inst (s->cbb, tree);
306 stmt: CEE_BGE_UN (fpcflags) {
307 tree->opcode = OP_FBGE_UN;
308 mono_bblock_add_inst (s->cbb, tree);
311 stmt: CEE_BLE (fpcflags) {
312 tree->opcode = OP_FBLE;
313 mono_bblock_add_inst (s->cbb, tree);
316 stmt: CEE_BLE_UN (fpcflags) {
317 tree->opcode = OP_FBLE_UN;
318 mono_bblock_add_inst (s->cbb, tree);
321 stmt: CEE_POP (freg) "0" {
325 freg: OP_LCONV_TO_R8 (lreg) {
326 /* nothing to do - emulated */
329 freg: OP_LCONV_TO_R4 (lreg) {
330 /* nothing to do - emulated */
333 freg: OP_LCONV_TO_R_UN (lreg) {
334 /* nothing to do - emulated */
337 freg: OP_FREM (freg, freg) {
338 /* nothing to do - emulated */
341 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
342 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
343 state->left->right->reg1);
346 reg: OP_CLT (OP_COMPARE (freg, freg)) {
347 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
348 state->left->right->reg1);
351 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
352 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
353 state->left->right->reg1);
356 reg: OP_CGT (OP_COMPARE (freg, freg)) {
357 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
358 state->left->right->reg1);
361 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
362 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
363 state->left->right->reg1);