1 #if defined(MONO_ARCH_SOFT_FLOAT)
2 #define SOFT_FLOAT_IMPL TRUE
4 #define SOFT_FLOAT_IMPL FALSE
15 # inssel-float.brg: burg file for floating point instructions
18 # Dietmar Maurer (dietmar@ximian.com)
20 # (C) 2002 Ximian, Inc.
27 freg: CEE_LDIND_R4 (base) {
28 if (SOFT_FLOAT_IMPL) {
29 g_assert_not_reached ();
31 MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADR4_MEMBASE, state->reg1,
32 state->left->tree->inst_basereg, state->left->tree->inst_offset);
36 freg: CEE_LDIND_R8 (base) {
37 if (SOFT_FLOAT_IMPL) {
38 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1,
39 state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
40 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg2,
41 state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
43 MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADR8_MEMBASE, state->reg1,
44 state->left->tree->inst_basereg, state->left->tree->inst_offset);
48 stmt: CEE_STIND_R4 (base, freg) {
49 if (SOFT_FLOAT_IMPL) {
50 g_assert_not_reached ();
52 MONO_EMIT_STORE_MEMBASE (s, tree, OP_STORER4_MEMBASE_REG, state->left->tree->inst_basereg,
53 state->left->tree->inst_offset, state->right->reg1);
57 stmt: CEE_STIND_R8 (base, freg) {
58 if (SOFT_FLOAT_IMPL) {
59 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
60 state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->reg2);
61 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
62 state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->reg1);
64 MONO_EMIT_STORE_MEMBASE (s, tree, OP_STORER8_MEMBASE_REG, state->left->tree->inst_basereg,
65 state->left->tree->inst_offset, state->right->reg1);
70 if (SOFT_FLOAT_IMPL) {
72 /* we load the r8 value */
73 d.vald = *(float*)tree->inst_p0;
74 MONO_EMIT_NEW_ICONST (s, state->reg1, d.vali [MINI_LS_WORD_IDX]);
75 MONO_EMIT_NEW_ICONST (s, state->reg2, d.vali [MINI_MS_WORD_IDX]);
77 tree->dreg = state->reg1;
78 mono_bblock_add_inst (s->cbb, tree);
83 if (SOFT_FLOAT_IMPL) {
85 d.vald = *(double*)tree->inst_p0;
86 MONO_EMIT_NEW_ICONST (s, state->reg1, d.vali [MINI_LS_WORD_IDX]);
87 MONO_EMIT_NEW_ICONST (s, state->reg2, d.vali [MINI_MS_WORD_IDX]);
89 tree->dreg = state->reg1;
90 mono_bblock_add_inst (s->cbb, tree);
98 freg: OP_FADD (freg, freg) {
99 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
102 freg: OP_FSUB (freg, freg) {
103 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
106 freg: OP_FMUL (freg, freg) {
107 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
110 freg: OP_FDIV (freg, freg) {
111 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
114 freg: OP_FREM (freg, freg) {
115 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
118 freg: OP_FNEG (freg) {
119 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
122 freg: OP_CKFINITE (freg) {
123 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
126 freg: OP_SIN (freg) {
127 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
130 freg: OP_COS (freg) {
131 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
134 freg: OP_ABS (freg) {
135 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
138 freg: OP_TAN (freg) {
139 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
142 freg: OP_ATAN (freg) {
143 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
146 freg: OP_SQRT (freg) {
147 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
151 # floating point conversions
154 reg: OP_FCONV_TO_I4 (freg) {
155 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
158 reg: OP_FCONV_TO_U4 (freg) {
159 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
162 reg: OP_FCONV_TO_OVF_I4 (freg) {
163 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
166 reg: OP_FCONV_TO_OVF_U4 (freg) {
167 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
170 reg: OP_FCONV_TO_OVF_I8 (freg) {
171 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
174 reg: OP_FCONV_TO_OVF_U8 (freg) {
175 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
178 reg: OP_FCONV_TO_OVF_I (freg) {
179 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
182 reg: OP_FCONV_TO_OVF_U (freg) {
183 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
186 reg: OP_FCONV_TO_I (freg) {
187 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
190 reg: OP_FCONV_TO_U (freg) {
191 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
194 reg: OP_FCONV_TO_I2 (freg) {
195 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
198 reg: OP_FCONV_TO_U2 (freg) {
199 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
202 reg: OP_FCONV_TO_I1 (freg) {
203 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
206 reg: OP_FCONV_TO_U1 (freg) {
207 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
210 freg: OP_FCONV_TO_R8 (freg) {
211 MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->reg1);
214 freg: OP_FCONV_TO_R4 (freg) {
215 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
218 freg: CEE_CONV_R4 (reg) "2" {
219 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
222 freg: CEE_CONV_R8 (reg) "2" {
223 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
226 freg: CEE_CONV_R_UN (reg) "2" {
227 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
234 # CPUs using the same condition flags for integers and float
235 # can use the following chain rule:
236 # cflags: fpcflags "0"
237 # that way all branches are handled by inssel.brg
239 fpcflags: OP_COMPARE (freg, freg) {
240 tree->opcode = OP_FCOMPARE;
241 tree->sreg1 = state->left->reg1;
242 tree->sreg2 = state->right->reg1;
243 mono_bblock_add_inst (s->cbb, tree);
247 # miscellaneous fp operations
250 stmt: CEE_POP (freg) {