llvm-runtime.h \
type-checking.c \
lldb.h \
- lldb.c
+ lldb.c \
+ memory-access.c
test_sources = \
basic-calls.cs \
--- /dev/null
+/**
+ * Emit memory access for the front-end.
+ *
+ */
+
+#include <config.h>
+#include <mono/utils/mono-compiler.h>
+
+#ifndef DISABLE_JIT
+
+#include "mini.h"
+#include "ir-emit.h"
+
+void
+mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val, int align)
+{
+ int val_reg;
+
+ g_assert (val == 0);
+
+ if (align == 0)
+ align = 4;
+
+ if ((size <= SIZEOF_REGISTER) && (size <= align)) {
+ switch (size) {
+ case 1:
+ MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI1_MEMBASE_IMM, destreg, offset, val);
+ return;
+ case 2:
+ MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI2_MEMBASE_IMM, destreg, offset, val);
+ return;
+ case 4:
+ MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI4_MEMBASE_IMM, destreg, offset, val);
+ return;
+#if SIZEOF_REGISTER == 8
+ case 8:
+ MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI8_MEMBASE_IMM, destreg, offset, val);
+ return;
+#endif
+ }
+ }
+
+ val_reg = alloc_preg (cfg);
+
+ if (SIZEOF_REGISTER == 8)
+ MONO_EMIT_NEW_I8CONST (cfg, val_reg, val);
+ else
+ MONO_EMIT_NEW_ICONST (cfg, val_reg, val);
+
+ if (align < 4) {
+ /* This could be optimized further if neccesary */
+ while (size >= 1) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
+ offset += 1;
+ size -= 1;
+ }
+ return;
+ }
+
+ if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
+ if (offset % 8) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
+ offset += 4;
+ size -= 4;
+ }
+ while (size >= 8) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
+ offset += 8;
+ size -= 8;
+ }
+ }
+
+ while (size >= 4) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
+ offset += 4;
+ size -= 4;
+ }
+ while (size >= 2) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
+ offset += 2;
+ size -= 2;
+ }
+ while (size >= 1) {
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
+ offset += 1;
+ size -= 1;
+ }
+}
+
+void
+mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align)
+{
+ int cur_reg;
+
+ if (align == 0)
+ align = 4;
+
+ /*FIXME arbitrary hack to avoid unbound code expansion.*/
+ g_assert (size < 10000);
+
+ if (align < 4) {
+ /* This could be optimized further if neccesary */
+ while (size >= 1) {
+ cur_reg = alloc_preg (cfg);
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
+ doffset += 1;
+ soffset += 1;
+ size -= 1;
+ }
+ }
+
+ if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
+ while (size >= 8) {
+ cur_reg = alloc_preg (cfg);
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI8_MEMBASE, cur_reg, srcreg, soffset);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, doffset, cur_reg);
+ doffset += 8;
+ soffset += 8;
+ size -= 8;
+ }
+ }
+
+ while (size >= 4) {
+ cur_reg = alloc_preg (cfg);
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, cur_reg, srcreg, soffset);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, doffset, cur_reg);
+ doffset += 4;
+ soffset += 4;
+ size -= 4;
+ }
+ while (size >= 2) {
+ cur_reg = alloc_preg (cfg);
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, cur_reg, srcreg, soffset);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, doffset, cur_reg);
+ doffset += 2;
+ soffset += 2;
+ size -= 2;
+ }
+ while (size >= 1) {
+ cur_reg = alloc_preg (cfg);
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
+ doffset += 1;
+ soffset += 1;
+ size -= 1;
+ }
+}
+
+#endif
return ins;
}
-static void
-mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val, int align)
-{
- int val_reg;
-
- g_assert (val == 0);
-
- if (align == 0)
- align = 4;
-
- if ((size <= SIZEOF_REGISTER) && (size <= align)) {
- switch (size) {
- case 1:
- MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI1_MEMBASE_IMM, destreg, offset, val);
- return;
- case 2:
- MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI2_MEMBASE_IMM, destreg, offset, val);
- return;
- case 4:
- MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI4_MEMBASE_IMM, destreg, offset, val);
- return;
-#if SIZEOF_REGISTER == 8
- case 8:
- MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI8_MEMBASE_IMM, destreg, offset, val);
- return;
-#endif
- }
- }
-
- val_reg = alloc_preg (cfg);
-
- if (SIZEOF_REGISTER == 8)
- MONO_EMIT_NEW_I8CONST (cfg, val_reg, val);
- else
- MONO_EMIT_NEW_ICONST (cfg, val_reg, val);
-
- if (align < 4) {
- /* This could be optimized further if neccesary */
- while (size >= 1) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
- offset += 1;
- size -= 1;
- }
- return;
- }
-
- if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
- if (offset % 8) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
- offset += 4;
- size -= 4;
- }
- while (size >= 8) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
- offset += 8;
- size -= 8;
- }
- }
-
- while (size >= 4) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
- offset += 4;
- size -= 4;
- }
- while (size >= 2) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
- offset += 2;
- size -= 2;
- }
- while (size >= 1) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
- offset += 1;
- size -= 1;
- }
-}
-
-void
-mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align)
-{
- int cur_reg;
-
- if (align == 0)
- align = 4;
-
- /*FIXME arbitrary hack to avoid unbound code expansion.*/
- g_assert (size < 10000);
-
- if (align < 4) {
- /* This could be optimized further if neccesary */
- while (size >= 1) {
- cur_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
- doffset += 1;
- soffset += 1;
- size -= 1;
- }
- }
-
- if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
- while (size >= 8) {
- cur_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI8_MEMBASE, cur_reg, srcreg, soffset);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, doffset, cur_reg);
- doffset += 8;
- soffset += 8;
- size -= 8;
- }
- }
-
- while (size >= 4) {
- cur_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, cur_reg, srcreg, soffset);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, doffset, cur_reg);
- doffset += 4;
- soffset += 4;
- size -= 4;
- }
- while (size >= 2) {
- cur_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, cur_reg, srcreg, soffset);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, doffset, cur_reg);
- doffset += 2;
- soffset += 2;
- size -= 2;
- }
- while (size >= 1) {
- cur_reg = alloc_preg (cfg);
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
- doffset += 1;
- soffset += 1;
- size -= 1;
- }
-}
-
static MonoInst*
mono_create_fast_tls_getter (MonoCompile *cfg, MonoTlsKey key)
{
void mono_remove_critical_edges (MonoCompile *cfg);
gboolean mono_is_regsize_var (MonoType *t);
void mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align);
+void mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val, int align);
void mini_emit_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native);
void mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass *klass);
MonoInst* mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck);