2 * Emit memory access for the front-end.
7 #include <mono/utils/mono-compiler.h>
11 #include <mono/utils/mono-memory-model.h>
17 mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val, int align)
26 if ((size <= SIZEOF_REGISTER) && (size <= align)) {
29 MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI1_MEMBASE_IMM, destreg, offset, val);
32 MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI2_MEMBASE_IMM, destreg, offset, val);
35 MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI4_MEMBASE_IMM, destreg, offset, val);
37 #if SIZEOF_REGISTER == 8
39 MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI8_MEMBASE_IMM, destreg, offset, val);
45 val_reg = alloc_preg (cfg);
47 if (SIZEOF_REGISTER == 8)
48 MONO_EMIT_NEW_I8CONST (cfg, val_reg, val);
50 MONO_EMIT_NEW_ICONST (cfg, val_reg, val);
53 /* This could be optimized further if neccesary */
55 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
62 if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
64 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
69 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
76 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
81 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
86 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
93 mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align)
100 /*FIXME arbitrary hack to avoid unbound code expansion.*/
101 g_assert (size < 10000);
104 /* This could be optimized further if neccesary */
106 cur_reg = alloc_preg (cfg);
107 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
108 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
115 if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
117 cur_reg = alloc_preg (cfg);
118 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI8_MEMBASE, cur_reg, srcreg, soffset);
119 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, doffset, cur_reg);
127 cur_reg = alloc_preg (cfg);
128 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, cur_reg, srcreg, soffset);
129 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, doffset, cur_reg);
135 cur_reg = alloc_preg (cfg);
136 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, cur_reg, srcreg, soffset);
137 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, doffset, cur_reg);
143 cur_reg = alloc_preg (cfg);
144 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
145 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
153 mini_emit_memory_load (MonoCompile *cfg, MonoType *type, MonoInst *src, int offset, int ins_flag)
157 EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, type, src->dreg, offset);
158 ins->flags |= ins_flag;
160 if (ins_flag & MONO_INST_VOLATILE) {
161 /* Volatile loads have acquire semantics, see 12.6.7 in Ecma 335 */
162 mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_ACQ);
170 mini_emit_memory_store (MonoCompile *cfg, MonoType *type, MonoInst *dest, MonoInst *value, int ins_flag)
174 if (ins_flag & MONO_INST_VOLATILE) {
175 /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
176 mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL);
178 /* FIXME: should check item at sp [1] is compatible with the type of the store. */
180 EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, type, dest->dreg, 0, value->dreg);
181 ins->flags |= ins_flag;
182 if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER &&
183 mini_type_is_reference (type) && !MONO_INS_IS_PCONST_NULL (value)) {
184 /* insert call to write barrier */
185 mini_emit_write_barrier (cfg, dest, value);