5 # inssel-alpha.brg: burg file for special Alpha instructions
8 # Sergey Tikhonov (tsv@solvo.ru)
10 # Derived work from other arches
15 stmt: OP_OUTARG_REG (reg) {
16 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
18 tree->opcode = OP_MOVE;
19 tree->sreg1 = state->left->reg1;
20 tree->dreg = mono_regstate_next_int (s->rs);
21 mono_bblock_add_inst (s->cbb, tree);
23 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
26 stmt: OP_OUTARG_FREG (freg) {
27 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
29 tree->opcode = OP_FMOVE;
30 tree->sreg1 = state->left->reg1;
31 tree->dreg = mono_regstate_next_float (s->rs);
32 mono_bblock_add_inst (s->cbb, tree);
34 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE);
37 stmt: OP_SETRET (reg) {
38 tree->opcode = OP_MOVE;
39 tree->sreg1 = state->left->reg1;
40 tree->dreg = alpha_r0;
41 mono_bblock_add_inst (s->cbb, tree);
44 stmt: OP_SETRET (freg) {
45 tree->opcode = OP_FMOVE;
46 tree->sreg1 = state->left->reg1;
47 tree->dreg = alpha_f0;
48 mono_bblock_add_inst (s->cbb, tree);
52 reg: OP_LOCALLOC (OP_ICONST) {
53 /* microcoded in mini-arm.c */
54 tree->sreg1 = mono_regstate_next_int (s->rs);
55 tree->dreg = state->reg1;
56 MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
57 mono_bblock_add_inst (s->cbb, tree);
60 reg: OP_LOCALLOC (reg) {
61 tree->dreg = state->reg1;
62 tree->sreg1 = state->left->reg1;
63 mono_bblock_add_inst (s->cbb, tree);
67 # This handles trees like outarg_vt (refanytype)
68 #stmt: OP_OUTARG_VT (reg, base) {
69 # MonoInst *stack_addr = state->right->tree;
71 # MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG,
72 # stack_addr->inst_basereg, stack_addr->inst_offset, state->left->reg1);
76 stmt: OP_OUTARG_REG (CEE_LDIND_I (base)),
77 stmt: OP_OUTARG_REG (CEE_LDIND_REF (base)),
78 stmt: OP_OUTARG_REG (CEE_LDIND_I1 (base)),
79 stmt: OP_OUTARG_REG (CEE_LDIND_U1 (base)),
80 stmt: OP_OUTARG_REG (CEE_LDIND_I2 (base)),
81 stmt: OP_OUTARG_REG (CEE_LDIND_U2 (base)),
82 stmt: OP_OUTARG_REG (CEE_LDIND_I4 (base)),
83 stmt: OP_OUTARG_REG (CEE_LDIND_U4 (base)),
84 stmt: OP_OUTARG_REG (CEE_LDIND_I8 (base)) {
85 /* FIXME: Move this to inssel.brg or inssel-long.brg */
86 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
88 MonoInst *base = state->left->left->tree;
90 dreg = mono_regstate_next_int (s->rs);
91 MONO_EMIT_LOAD_MEMBASE_OP (s, tree, ldind_to_load_membase (state->left->tree->opcode),
92 dreg, base->inst_basereg, base->inst_offset);
94 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
97 stmt: OP_OUTARG_REG (OP_I8CONST) {
98 /* FIXME: Move this to inssel.brg or inssel-long.brg */
99 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
101 tree->opcode = OP_I8CONST;
102 tree->inst_c0 = state->left->tree->inst_c0;
103 tree->dreg = mono_regstate_next_int (s->rs);
104 mono_bblock_add_inst (s->cbb, tree);
106 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
109 stmt: OP_OUTARG_REG (OP_ICONST) {
110 /* FIXME: Move this to inssel.brg or inssel-long.brg */
111 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
113 tree->opcode = OP_ICONST;
114 tree->inst_c0 = state->left->tree->inst_c0;
115 tree->dreg = mono_regstate_next_int (s->rs);
116 mono_bblock_add_inst (s->cbb, tree);
118 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
121 stmt: OP_OUTARG_REG (CEE_LDIND_I (OP_REGVAR)),
122 stmt: OP_OUTARG_REG (CEE_LDIND_I8 (OP_REGVAR)),
123 stmt: OP_OUTARG_REG (CEE_LDIND_I4 (OP_REGVAR)),
124 stmt: OP_OUTARG_REG (CEE_LDIND_U4 (OP_REGVAR)),
125 stmt: OP_OUTARG_REG (CEE_LDIND_REF (OP_REGVAR)) {
126 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
128 tree->opcode = OP_MOVE;
129 tree->sreg1 = state->left->left->tree->dreg;
130 tree->dreg = mono_regstate_next_int (s->rs);
131 mono_bblock_add_inst (s->cbb, tree);
133 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
136 stmt: OP_OUTARG_REG (OP_LDADDR (OP_REGOFFSET)),
137 stmt: OP_OUTARG_REG (CEE_LDOBJ (OP_REGOFFSET)) {
138 /* FIXME: Move this to inssel.brg */
139 MonoCallInst *call = (MonoCallInst*)tree->inst_right;
141 tree->opcode = OP_ADD_IMM;
142 tree->sreg1 = state->left->left->tree->inst_basereg;
143 tree->inst_imm = state->left->left->tree->inst_offset;
144 tree->dreg = mono_regstate_next_int (s->rs);
145 mono_bblock_add_inst (s->cbb, tree);
147 mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE);
150 stmt: OP_OUTARG (reg) {
151 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, alpha_sp,
152 tree->dreg, state->left->reg1);
155 stmt: OP_OUTARG (freg) {
156 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, alpha_sp,
157 tree->dreg, state->left->reg1);
160 stmt: OP_OUTARG_R4 (freg) {
161 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, alpha_sp,
162 tree->dreg, state->left->reg1);
165 stmt: OP_OUTARG_R8 (freg) {
166 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, alpha_sp,
167 tree->dreg, state->left->reg1);
170 stmt: OP_OUTARG_VT (CEE_LDOBJ (base), base) {
171 MonoInst *vt = state->left->left->tree;
172 MonoInst *stack_addr = state->right->tree;
173 int sz = stack_addr->inst_imm;
178 mini_emit_memcpy (s, stack_addr->inst_basereg, stack_addr->inst_offset,
179 vt->inst_basereg, vt->inst_offset, sz, 0);
182 # This handles trees like outarg_vt (refanytype)
183 stmt: OP_OUTARG_VT (reg, base) {
184 MonoInst *stack_addr = state->right->tree;
186 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI8_MEMBASE_REG, stack_addr->inst_basereg, stack_addr->inst_offset, state->left->reg1);
189 stmt: OP_START_HANDLER {
190 MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
191 tree->inst_left = spvar;
192 mono_bblock_add_inst (s->cbb, tree);
195 stmt: CEE_ENDFINALLY {
196 MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
197 tree->inst_left = spvar;
198 mono_bblock_add_inst (s->cbb, tree);
201 stmt: OP_ENDFILTER (reg) {
202 MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
203 tree->inst_left = spvar;
204 tree->sreg1 = state->left->reg1;
205 mono_bblock_add_inst (s->cbb, tree);
208 stmt: CEE_SWITCH (reg) {
210 int offset_reg = mono_regstate_next_int (s->rs);
211 int target_reg = mono_regstate_next_int (s->rs);
212 int n = GPOINTER_TO_INT (tree->klass);
214 MONO_NEW_LABEL (s, label);
216 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, n);
217 MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_many_bb [n]);
218 if (sizeof (gpointer) == 8)
219 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, offset_reg,
220 state->left->reg1, 3);
222 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, offset_reg,
223 state->left->reg1, 2);
224 mono_bblock_add_inst (s->cbb, label);
225 if (s->compile_aot) {
226 int table_reg = mono_regstate_next_int (s->rs);
227 int sum_reg = mono_regstate_next_int (s->rs);
228 MonoJumpInfoBBTable *table;
230 table = mono_mempool_alloc (s->mempool,
231 sizeof (MonoJumpInfoBBTable));
232 table->table = tree->inst_many_bb;
233 table->table_size = n;
235 MONO_EMIT_NEW_AOTCONST (s, table_reg, table,
236 MONO_PATCH_INFO_SWITCH);
238 MONO_EMIT_NEW_BIALU (s, CEE_ADD, sum_reg, table_reg,
240 MONO_EMIT_NEW_LOAD_MEMBASE (s, target_reg, sum_reg, 0);
242 mono_create_jump_table (s, label, tree->inst_many_bb, n);
244 /* On Alpha GP points to the beginning of procedure.
248 br ... skip two longs
249 2 longs = jump table address
250 addq at, offset_reg, dest_reg
253 MONO_EMIT_NEW_UNALU(s, OP_MOVE, alpha_at, alpha_at);
254 MONO_EMIT_NEW_UNALU(s, OP_MOVE, alpha_at, alpha_at);
255 MONO_EMIT_NEW_UNALU(s, OP_MOVE, alpha_at, alpha_at);
256 MONO_EMIT_NEW_UNALU(s, OP_MOVE, alpha_at, alpha_at);
257 MONO_EMIT_NEW_UNALU(s, OP_MOVE, alpha_at, alpha_at);
258 MONO_EMIT_NEW_UNALU(s, OP_MOVE, alpha_at, alpha_at);
260 MONO_EMIT_NEW_BIALU (s, CEE_ADD, target_reg, alpha_at,
262 MONO_EMIT_NEW_LOAD_MEMBASE (s, target_reg,
265 /* the backend must patch the address.
266 we use 0xf0f0f0f0 to avoid the usage
267 * of special (short) opcodes on x86
268 if (sizeof (gpointer) == 8)
269 MONO_EMIT_NEW_LOAD_MEMBASE (s, target_reg,
270 offset_reg, (long)0xf0f0f0f0f0f0f0f1LL);
272 MONO_EMIT_NEW_LOAD_MEMBASE (s, target_reg,
273 offset_reg, 0xf0f0f0f0);
276 MONO_EMIT_UNALU (s, tree, OP_BR_REG, -1, target_reg);
279 reg: CEE_LDIND_I1 (OP_REGVAR) {
280 MONO_EMIT_UNALU (s, tree, OP_SEXT_I1, state->reg1,
281 state->left->tree->dreg);
284 reg: CEE_LDIND_I2 (OP_REGVAR) {
285 MONO_EMIT_UNALU (s, tree, OP_SEXT_I2, state->reg1,
286 state->left->tree->dreg);
290 #stmt: CEE_BEQ (fpcflags) {
291 # tree->opcode = OP_FBEQ;
292 # mono_bblock_add_inst (s->cbb, tree);
295 #stmt: CEE_BNE_UN (fpcflags) {
296 # tree->opcode = OP_FBNE_UN;
297 # mono_bblock_add_inst (s->cbb, tree);
300 #stmt: CEE_BLT (fpcflags) {
301 # tree->opcode = OP_FBLT;
302 # mono_bblock_add_inst (s->cbb, tree);
305 #stmt: CEE_BLT_UN (fpcflags) {
306 # tree->opcode = OP_FBLT_UN;
307 # mono_bblock_add_inst (s->cbb, tree);
310 #stmt: CEE_BGT (fpcflags) {
311 # tree->opcode = OP_FBGT;
312 # mono_bblock_add_inst (s->cbb, tree);
315 #stmt: CEE_BGT_UN (fpcflags) {
316 # tree->opcode = OP_FBGT_UN;
317 # mono_bblock_add_inst (s->cbb, tree);
320 #stmt: CEE_BGE (fpcflags) {
321 # tree->opcode = OP_FBGE;
322 # mono_bblock_add_inst (s->cbb, tree);
325 #stmt: CEE_BGE_UN (fpcflags) {
326 # tree->opcode = OP_FBGE_UN;
327 # mono_bblock_add_inst (s->cbb, tree);
330 #stmt: CEE_BLE (fpcflags) {
331 # tree->opcode = OP_FBLE;
332 # mono_bblock_add_inst (s->cbb, tree);
335 #stmt: CEE_BLE_UN (fpcflags) {
336 # tree->opcode = OP_FBLE_UN;
337 # mono_bblock_add_inst (s->cbb, tree);
341 stmt: CEE_BLT_UN (OP_COMPARE (freg, freg)) {
342 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_UN_SU, (alpha_at+1),
343 state->left->left->reg1, state->left->right->reg1);
344 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LT_SU, alpha_at,
345 state->left->left->reg1, state->left->right->reg1);
346 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
348 MONO_EMIT_UNALU (s, tree, OP_FBLT_UN, -1, -1);
351 stmt: CEE_BLE_UN (OP_COMPARE (freg, freg)) {
352 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_UN_SU, (alpha_at+1),
353 state->left->left->reg1, state->left->right->reg1);
354 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LE_SU, alpha_at,
355 state->left->left->reg1, state->left->right->reg1);
356 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
358 MONO_EMIT_UNALU (s, tree, OP_FBLE_UN, -1, -1);
361 stmt: CEE_BGT_UN (OP_COMPARE (freg, freg)) {
362 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_UN_SU, (alpha_at+1),
363 state->left->left->reg1, state->left->right->reg1);
364 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LE_SU, alpha_at,
365 state->left->left->reg1, state->left->right->reg1);
366 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
368 MONO_EMIT_UNALU (s, tree, OP_FBGT_UN, -1, -1);
371 stmt: CEE_BGE_UN (OP_COMPARE (freg, freg)) {
372 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_UN_SU, (alpha_at+1),
373 state->left->left->reg1, state->left->right->reg1);
374 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LT_SU, alpha_at,
375 state->left->left->reg1, state->left->right->reg1);
376 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
378 MONO_EMIT_UNALU (s, tree, OP_FBGE_UN, -1, -1);
381 reg: OP_CEQ (OP_COMPARE (freg, freg)) {
382 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_EQ_SU, alpha_at,
383 state->left->left->reg1, state->left->right->reg1);
384 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
386 tree->opcode = OP_FCEQ;
387 mono_bblock_add_inst (s->cbb, tree);
390 reg: OP_CLT (OP_COMPARE (freg, freg)) {
391 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LT_SU, alpha_at,
392 state->left->left->reg1, state->left->right->reg1);
393 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
395 tree->opcode = OP_FCLT;
396 mono_bblock_add_inst (s->cbb, tree);
399 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
400 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_UN_SU, (alpha_at+1),
401 state->left->right->reg1, state->left->left->reg1);
402 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LT_SU, alpha_at,
403 state->left->left->reg1, state->left->right->reg1);
404 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
406 tree->opcode = OP_FCLT_UN;
407 mono_bblock_add_inst (s->cbb, tree);
411 reg: OP_CGT (OP_COMPARE (freg, freg)) {
412 // Same as CLT_n (OP_COMPARE) - just exchange parameters
413 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LT_SU, alpha_at,
414 // state->left->left->reg1, state->left->right->reg1);
415 state->left->right->reg1, state->left->left->reg1);
416 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
418 // tree->opcode = OP_FCGT;
419 tree->opcode = OP_FCLT;
420 mono_bblock_add_inst (s->cbb, tree);
423 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
425 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_UN_SU, (alpha_at+1),
426 state->left->right->reg1, state->left->left->reg1);
427 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_LT_SU, alpha_at,
428 state->left->right->reg1, state->left->left->reg1);
429 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
431 tree->opcode = OP_FCLT_UN;
432 mono_bblock_add_inst (s->cbb, tree);
436 stmt: CEE_BEQ (OP_COMPARE (freg, freg)) {
437 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_EQ_SU, alpha_at,
438 state->left->left->reg1, state->left->right->reg1);
439 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
441 MONO_EMIT_UNALU (s, tree, OP_FBEQ, -1, -1);
444 stmt: CEE_BNE_UN (OP_COMPARE (freg, freg)) {
445 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_UN_SU, (alpha_at+1),
446 state->left->left->reg1, state->left->right->reg1);
447 MONO_EMIT_NEW_BIALU (s, OP_ALPHA_CMPT_EQ_SU, alpha_at,
448 state->left->left->reg1, state->left->right->reg1);
449 MONO_EMIT_NEW_UNALU (s, OP_ALPHA_TRAPB, -1, -1);
451 MONO_EMIT_UNALU (s, tree, OP_FBNE_UN, -1, -1);
455 fpcflags: OP_COMPARE (freg, freg) {
456 tree->opcode = OP_FCOMPARE;
457 mono_bblock_add_inst (s->cbb, tree);
459 reg: OP_CEQ (fpcflags) {
460 tree->dreg = state->reg1;
461 tree->opcode = OP_FCEQ;
462 mono_bblock_add_inst (s->cbb, tree);
465 reg: OP_CLT (fpcflags) {
466 tree->dreg = state->reg1;
467 tree->opcode = OP_FCLT;
468 mono_bblock_add_inst (s->cbb, tree);
471 reg: OP_CLT_UN (fpcflags) {
472 tree->dreg = state->reg1;
473 tree->opcode = OP_FCLT_UN;
474 mono_bblock_add_inst (s->cbb, tree);
477 reg: OP_CGT (fpcflags) {
478 tree->dreg = state->reg1;
479 tree->opcode = OP_FCGT;
480 mono_bblock_add_inst (s->cbb, tree);
483 reg: OP_CGT_UN (fpcflags) {
484 tree->dreg = state->reg1;
485 tree->opcode = OP_FCGT_UN;
486 mono_bblock_add_inst (s->cbb, tree);
489 reg: OP_LCONV_TO_I4 (reg) "0" {
490 /* Sign extend the value in the lower word into the upper word */
491 MONO_EMIT_BIALU_IMM (s, tree, CEE_CONV_I4, state->reg1,
492 state->left->reg1, 0);
495 reg: OP_LCONV_TO_U4 (reg) "0" {
496 /* Clean out the upper word */
497 MONO_EMIT_BIALU_IMM (s, tree, CEE_CONV_U4, state->reg1,
498 state->left->reg1, 0);
501 freg: OP_LCONV_TO_R8 (reg) {
502 /* FIXME: Move this inssel-long.brg */
503 tree->sreg1 = state->left->reg1;
504 tree->dreg = state->reg1;
505 mono_bblock_add_inst (s->cbb, tree);
508 freg: OP_LCONV_TO_R4 (reg) {
509 /* FIXME: Move this inssel-long.brg */
510 tree->sreg1 = state->left->reg1;
511 tree->dreg = state->reg1;
512 mono_bblock_add_inst (s->cbb, tree);