[jit] Move memcpy and memset emmiters to new file called memory-access.c
[mono.git] / mono / mini / memory-access.c
1 /**
2  * Emit memory access for the front-end.
3  *
4  */
5
6 #include <config.h>
7 #include <mono/utils/mono-compiler.h>
8
9 #ifndef DISABLE_JIT
10
11 #include "mini.h"
12 #include "ir-emit.h"
13
14 void 
15 mini_emit_memset (MonoCompile *cfg, int destreg, int offset, int size, int val, int align)
16 {
17         int val_reg;
18
19         g_assert (val == 0);
20
21         if (align == 0)
22                 align = 4;
23
24         if ((size <= SIZEOF_REGISTER) && (size <= align)) {
25                 switch (size) {
26                 case 1:
27                         MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI1_MEMBASE_IMM, destreg, offset, val);
28                         return;
29                 case 2:
30                         MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI2_MEMBASE_IMM, destreg, offset, val);
31                         return;
32                 case 4:
33                         MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI4_MEMBASE_IMM, destreg, offset, val);
34                         return;
35 #if SIZEOF_REGISTER == 8
36                 case 8:
37                         MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STOREI8_MEMBASE_IMM, destreg, offset, val);
38                         return;
39 #endif
40                 }
41         }
42
43         val_reg = alloc_preg (cfg);
44
45         if (SIZEOF_REGISTER == 8)
46                 MONO_EMIT_NEW_I8CONST (cfg, val_reg, val);
47         else
48                 MONO_EMIT_NEW_ICONST (cfg, val_reg, val);
49
50         if (align < 4) {
51                 /* This could be optimized further if neccesary */
52                 while (size >= 1) {
53                         MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
54                         offset += 1;
55                         size -= 1;
56                 }
57                 return;
58         }       
59
60         if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
61                 if (offset % 8) {
62                         MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
63                         offset += 4;
64                         size -= 4;
65                 }
66                 while (size >= 8) {
67                         MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, offset, val_reg);
68                         offset += 8;
69                         size -= 8;
70                 }
71         }       
72
73         while (size >= 4) {
74                 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, offset, val_reg);
75                 offset += 4;
76                 size -= 4;
77         }
78         while (size >= 2) {
79                 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, offset, val_reg);
80                 offset += 2;
81                 size -= 2;
82         }
83         while (size >= 1) {
84                 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, offset, val_reg);
85                 offset += 1;
86                 size -= 1;
87         }
88 }
89
90 void 
91 mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int soffset, int size, int align)
92 {
93         int cur_reg;
94
95         if (align == 0)
96                 align = 4;
97
98         /*FIXME arbitrary hack to avoid unbound code expansion.*/
99         g_assert (size < 10000);
100
101         if (align < 4) {
102                 /* This could be optimized further if neccesary */
103                 while (size >= 1) {
104                         cur_reg = alloc_preg (cfg);
105                         MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
106                         MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
107                         doffset += 1;
108                         soffset += 1;
109                         size -= 1;
110                 }
111         }
112
113         if (!cfg->backend->no_unaligned_access && SIZEOF_REGISTER == 8) {
114                 while (size >= 8) {
115                         cur_reg = alloc_preg (cfg);
116                         MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI8_MEMBASE, cur_reg, srcreg, soffset);
117                         MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, destreg, doffset, cur_reg);
118                         doffset += 8;
119                         soffset += 8;
120                         size -= 8;
121                 }
122         }       
123
124         while (size >= 4) {
125                 cur_reg = alloc_preg (cfg);
126                 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, cur_reg, srcreg, soffset);
127                 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, destreg, doffset, cur_reg);
128                 doffset += 4;
129                 soffset += 4;
130                 size -= 4;
131         }
132         while (size >= 2) {
133                 cur_reg = alloc_preg (cfg);
134                 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, cur_reg, srcreg, soffset);
135                 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, destreg, doffset, cur_reg);
136                 doffset += 2;
137                 soffset += 2;
138                 size -= 2;
139         }
140         while (size >= 1) {
141                 cur_reg = alloc_preg (cfg);
142                 MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, srcreg, soffset);
143                 MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, destreg, doffset, cur_reg);
144                 doffset += 1;
145                 soffset += 1;
146                 size -= 1;
147         }
148 }
149
150 #endif