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) {
97 tree->opcode = OP_SETREG;
98 tree->dreg = tree->unused;
99 tree->sreg1 = state->left->reg1;
100 mono_bblock_add_inst (s->cbb, tree);
103 stmt: OP_OUTARG (OP_REGVAR) {
104 tree->opcode = OP_SETREG;
105 tree->dreg = tree->unused;
106 tree->sreg1 = state->left->tree->dreg;
107 mono_bblock_add_inst (s->cbb, tree);
110 stmt: OP_OUTARG (lreg) {
111 MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
112 tree->opcode = OP_SETREG;
113 tree->dreg = tree->unused + 1;
114 tree->sreg1 = state->left->reg1;
115 mono_bblock_add_inst (s->cbb, tree);
118 stmt: OP_OUTARG (OP_ICONST) {
119 tree->opcode = OP_SETREGIMM;
120 tree->dreg = tree->unused;
121 tree->inst_c0 = state->left->tree->inst_c0;
122 mono_bblock_add_inst (s->cbb, tree);
125 #stmt: OP_OUTARG (CEE_LDIND_I4 (base)) {
126 # tree->opcode = OP_X86_PUSH_MEMBASE;
127 # tree->inst_basereg = state->left->left->tree->inst_basereg;
128 # tree->inst_offset = state->left->left->tree->inst_offset;
129 # mono_bblock_add_inst (s->cbb, tree);
132 #stmt: OP_OUTARG (CEE_LDIND_U4 (base)) {
133 # tree->opcode = OP_X86_PUSH_MEMBASE;
134 # tree->inst_basereg = state->left->left->tree->inst_basereg;
135 # tree->inst_offset = state->left->left->tree->inst_offset;
136 # mono_bblock_add_inst (s->cbb, tree);
139 #stmt: OP_OUTARG (CEE_LDIND_I (base)) {
140 # tree->opcode = OP_X86_PUSH_MEMBASE;
141 # tree->inst_basereg = state->left->left->tree->inst_basereg;
142 # tree->inst_offset = state->left->left->tree->inst_offset;
143 # mono_bblock_add_inst (s->cbb, tree);
146 #stmt: OP_OUTARG (CEE_LDIND_REF (base)) {
147 # tree->opcode = OP_X86_PUSH_MEMBASE;
148 # tree->inst_basereg = state->left->left->tree->inst_basereg;
149 # tree->inst_offset = state->left->left->tree->inst_offset;
150 # mono_bblock_add_inst (s->cbb, tree);
153 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
154 tree->opcode = OP_SETREG;
155 tree->sreg1 = state->left->left->tree->dreg;
156 tree->dreg = tree->unused;
157 mono_bblock_add_inst (s->cbb, tree);
160 #stmt: OP_OUTARG (CEE_LDOBJ (reg)) {
161 # tree->opcode = OP_X86_PUSH;
162 # tree->sreg1 = state->left->reg1;
163 # mono_bblock_add_inst (s->cbb, tree);
166 stmt: OP_OUTARG (freg) {
167 tree->opcode = OP_SETFREG;
168 tree->sreg1 = state->left->reg1;
169 tree->dreg = tree->unused;
170 mono_bblock_add_inst (s->cbb, tree);
173 stmt: OP_OUTARG_R4 (freg) {
174 tree->opcode = OP_SETFREG;
175 tree->sreg1 = state->left->reg1;
176 tree->dreg = tree->unused;
177 mono_bblock_add_inst (s->cbb, tree);
180 stmt: OP_OUTARG_R8 (freg) {
181 tree->opcode = OP_SETFREG;
182 tree->sreg1 = state->left->reg1;
183 tree->dreg = tree->unused;
184 mono_bblock_add_inst (s->cbb, tree);
187 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
188 MonoInst *vt = state->left->left->tree;
189 int start_reg = tree->unused & 0xff;
190 int nregs = (tree->unused >> 8) & 0xff;
191 int ovf_size = (tree->unused >> 16) & 0xffff;
192 int i, tmpr, soffset;
193 soffset = vt->inst_offset;
194 for (i = 0; i < nregs; ++i) {
195 tmpr = mono_regstate_next_int (s->rs);
196 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, vt->inst_basereg, soffset);
197 MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg + i, tmpr);
198 soffset += sizeof (gpointer);
200 //g_print ("vt size: %d at R%d + %d\n", tree->inst_imm, vt->inst_basereg, vt->inst_offset);
201 g_assert (ovf_size == 0); /* not yet supported */
204 stmt: OP_OUTARG_VT (OP_ICONST) {
205 int start_reg = tree->unused & 0xff;
206 int nregs = (tree->unused >> 8) & 0xff;
207 int ovf_size = (tree->unused >> 16) & 0xffff;
209 tree->opcode = OP_SETREGIMM;
210 tree->dreg = start_reg;
211 tree->inst_c0 = state->left->tree->inst_c0;
212 mono_bblock_add_inst (s->cbb, tree);
214 g_assert_not_reached ();
218 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
219 /* nothing to do: the value is already on the FP stack */
222 stmt: CEE_BNE_UN (fpcflags) {
223 tree->opcode = OP_FBNE_UN;
224 mono_bblock_add_inst (s->cbb, tree);
227 stmt: CEE_BEQ (fpcflags) {
228 tree->opcode = OP_FBEQ;
229 mono_bblock_add_inst (s->cbb, tree);
232 stmt: CEE_BLT (fpcflags) {
233 tree->opcode = OP_FBLT;
234 mono_bblock_add_inst (s->cbb, tree);
237 stmt: CEE_BLT_UN (fpcflags) {
238 tree->opcode = OP_FBLT_UN;
239 mono_bblock_add_inst (s->cbb, tree);
242 stmt: CEE_BGT (fpcflags) {
243 tree->opcode = OP_FBGT;
244 mono_bblock_add_inst (s->cbb, tree);
247 stmt: CEE_BGT_UN (fpcflags) {
248 tree->opcode = OP_FBGT_UN;
249 mono_bblock_add_inst (s->cbb, tree);
252 stmt: CEE_BGE (fpcflags) {
253 tree->opcode = OP_FBGE;
254 mono_bblock_add_inst (s->cbb, tree);
257 stmt: CEE_BGE_UN (fpcflags) {
258 tree->opcode = OP_FBGE_UN;
259 mono_bblock_add_inst (s->cbb, tree);
262 stmt: CEE_BLE (fpcflags) {
263 tree->opcode = OP_FBLE;
264 mono_bblock_add_inst (s->cbb, tree);
267 stmt: CEE_BLE_UN (fpcflags) {
268 tree->opcode = OP_FBLE_UN;
269 mono_bblock_add_inst (s->cbb, tree);
272 stmt: CEE_POP (freg) "0" {
276 freg: OP_LCONV_TO_R8 (lreg) {
277 /* nothing to do - emulated */
280 freg: OP_LCONV_TO_R4 (lreg) {
281 /* nothing to do - emulated */
284 freg: OP_LCONV_TO_R_UN (lreg) {
285 /* nothing to do - emulated */
288 freg: OP_FREM (freg, freg) {
289 /* nothing to do - emulated */
292 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
293 MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
294 state->left->right->reg1);
297 reg: OP_CLT (OP_COMPARE (freg, freg)) {
298 MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
299 state->left->right->reg1);
302 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
303 MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
304 state->left->right->reg1);
307 reg: OP_CGT (OP_COMPARE (freg, freg)) {
308 MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
309 state->left->right->reg1);
312 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
313 MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
314 state->left->right->reg1);