ARM TCG conversion 5/16.
[qemu] / target-arm / op_mem.h
1 /* ARM memory operations.  */
2
3 void helper_ld(uint32_t);
4 /* Load from address T1 into T0.  */
5 #define MEM_LD_OP(name) \
6 void OPPROTO glue(op_ld##name,MEMSUFFIX)(void) \
7 { \
8     T0 = glue(ld##name,MEMSUFFIX)(T1); \
9     FORCE_RET(); \
10 }
11
12 MEM_LD_OP(ub)
13 MEM_LD_OP(sb)
14 MEM_LD_OP(uw)
15 MEM_LD_OP(sw)
16 MEM_LD_OP(l)
17
18 #undef MEM_LD_OP
19
20 /* Store T0 to address T1.  */
21 #define MEM_ST_OP(name) \
22 void OPPROTO glue(op_st##name,MEMSUFFIX)(void) \
23 { \
24     glue(st##name,MEMSUFFIX)(T1, T0); \
25     FORCE_RET(); \
26 }
27
28 MEM_ST_OP(b)
29 MEM_ST_OP(w)
30 MEM_ST_OP(l)
31
32 #undef MEM_ST_OP
33
34 /* Swap T0 with memory at address T1.  */
35 /* ??? Is this exception safe?  */
36 #define MEM_SWP_OP(name, lname) \
37 void OPPROTO glue(op_swp##name,MEMSUFFIX)(void) \
38 { \
39     uint32_t tmp; \
40     cpu_lock(); \
41     tmp = glue(ld##lname,MEMSUFFIX)(T1); \
42     glue(st##name,MEMSUFFIX)(T1, T0); \
43     T0 = tmp; \
44     cpu_unlock(); \
45     FORCE_RET(); \
46 }
47
48 MEM_SWP_OP(b, ub)
49 MEM_SWP_OP(l, l)
50
51 #undef MEM_SWP_OP
52
53 /* Load-locked, store exclusive.  */
54 #define EXCLUSIVE_OP(suffix, ldsuffix) \
55 void OPPROTO glue(op_ld##suffix##ex,MEMSUFFIX)(void) \
56 { \
57     cpu_lock(); \
58     helper_mark_exclusive(env, T1); \
59     T0 = glue(ld##ldsuffix,MEMSUFFIX)(T1); \
60     cpu_unlock(); \
61     FORCE_RET(); \
62 } \
63  \
64 void OPPROTO glue(op_st##suffix##ex,MEMSUFFIX)(void) \
65 { \
66     int failed; \
67     cpu_lock(); \
68     failed = helper_test_exclusive(env, T1); \
69     /* ??? Is it safe to hold the cpu lock over a store?  */ \
70     if (!failed) { \
71         glue(st##suffix,MEMSUFFIX)(T1, T0); \
72     } \
73     T0 = failed; \
74     cpu_unlock(); \
75     FORCE_RET(); \
76 }
77
78 EXCLUSIVE_OP(b, ub)
79 EXCLUSIVE_OP(w, uw)
80 EXCLUSIVE_OP(l, l)
81
82 #undef EXCLUSIVE_OP
83
84 /* Load exclusive T0:T1 from address T1.  */
85 void OPPROTO glue(op_ldqex,MEMSUFFIX)(void)
86 {
87     cpu_lock();
88     helper_mark_exclusive(env, T1);
89     T0 = glue(ldl,MEMSUFFIX)(T1);
90     T1 = glue(ldl,MEMSUFFIX)((T1 + 4));
91     cpu_unlock();
92     FORCE_RET();
93 }
94
95 /* Store exclusive T0:T2 to address T1.  */
96 void OPPROTO glue(op_stqex,MEMSUFFIX)(void)
97 {
98     int failed;
99     cpu_lock();
100     failed = helper_test_exclusive(env, T1);
101     /* ??? Is it safe to hold the cpu lock over a store?  */
102     if (!failed) {
103         glue(stl,MEMSUFFIX)(T1, T0);
104         glue(stl,MEMSUFFIX)((T1 + 4), T2);
105     }
106     T0 = failed;
107     cpu_unlock();
108     FORCE_RET();
109 }
110
111 /* Floating point load/store.  Address is in T1 */
112 #define VFP_MEM_OP(p, w) \
113 void OPPROTO glue(op_vfp_ld##p,MEMSUFFIX)(void) \
114 { \
115     FT0##p = glue(ldf##w,MEMSUFFIX)(T1); \
116     FORCE_RET(); \
117 } \
118 void OPPROTO glue(op_vfp_st##p,MEMSUFFIX)(void) \
119 { \
120     glue(stf##w,MEMSUFFIX)(T1, FT0##p); \
121     FORCE_RET(); \
122 }
123
124 VFP_MEM_OP(s,l)
125 VFP_MEM_OP(d,q)
126
127 #undef VFP_MEM_OP
128
129 /* iwMMXt load/store.  Address is in T1 */
130 #define MMX_MEM_OP(name, ldname) \
131 void OPPROTO glue(op_iwmmxt_ld##name,MEMSUFFIX)(void) \
132 { \
133     M0 = glue(ld##ldname,MEMSUFFIX)(T1); \
134     FORCE_RET(); \
135 } \
136 void OPPROTO glue(op_iwmmxt_st##name,MEMSUFFIX)(void) \
137 { \
138     glue(st##name,MEMSUFFIX)(T1, M0); \
139     FORCE_RET(); \
140 }
141
142 MMX_MEM_OP(b, ub)
143 MMX_MEM_OP(w, uw)
144 MMX_MEM_OP(l, l)
145 MMX_MEM_OP(q, q)
146
147 #undef MMX_MEM_OP
148
149 #undef MEMSUFFIX