Revision 1a2fb1c0 target-sparc/translate.c
b/target-sparc/translate.c | ||
---|---|---|
36 | 36 |
#include "cpu.h" |
37 | 37 |
#include "exec-all.h" |
38 | 38 |
#include "disas.h" |
39 |
#include "helper.h" |
|
39 | 40 |
#include "tcg-op.h" |
40 | 41 |
|
41 | 42 |
#define DEBUG_DISAS |
... | ... | |
44 | 45 |
#define JUMP_PC 2 /* dynamic pc value which takes only two values |
45 | 46 |
according to jump_pc[T2] */ |
46 | 47 |
|
48 |
/* global register indexes */ |
|
49 |
static TCGv cpu_env, cpu_T[3], cpu_regwptr; |
|
50 |
/* local register indexes (only used inside old micro ops) */ |
|
51 |
static TCGv cpu_tmp0; |
|
52 |
|
|
47 | 53 |
typedef struct DisasContext { |
48 | 54 |
target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */ |
49 | 55 |
target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */ |
... | ... | |
102 | 108 |
|
103 | 109 |
static void disas_sparc_insn(DisasContext * dc); |
104 | 110 |
|
105 |
static GenOpFunc * const gen_op_movl_TN_reg[2][32] = { |
|
106 |
{ |
|
107 |
gen_op_movl_g0_T0, |
|
108 |
gen_op_movl_g1_T0, |
|
109 |
gen_op_movl_g2_T0, |
|
110 |
gen_op_movl_g3_T0, |
|
111 |
gen_op_movl_g4_T0, |
|
112 |
gen_op_movl_g5_T0, |
|
113 |
gen_op_movl_g6_T0, |
|
114 |
gen_op_movl_g7_T0, |
|
115 |
gen_op_movl_o0_T0, |
|
116 |
gen_op_movl_o1_T0, |
|
117 |
gen_op_movl_o2_T0, |
|
118 |
gen_op_movl_o3_T0, |
|
119 |
gen_op_movl_o4_T0, |
|
120 |
gen_op_movl_o5_T0, |
|
121 |
gen_op_movl_o6_T0, |
|
122 |
gen_op_movl_o7_T0, |
|
123 |
gen_op_movl_l0_T0, |
|
124 |
gen_op_movl_l1_T0, |
|
125 |
gen_op_movl_l2_T0, |
|
126 |
gen_op_movl_l3_T0, |
|
127 |
gen_op_movl_l4_T0, |
|
128 |
gen_op_movl_l5_T0, |
|
129 |
gen_op_movl_l6_T0, |
|
130 |
gen_op_movl_l7_T0, |
|
131 |
gen_op_movl_i0_T0, |
|
132 |
gen_op_movl_i1_T0, |
|
133 |
gen_op_movl_i2_T0, |
|
134 |
gen_op_movl_i3_T0, |
|
135 |
gen_op_movl_i4_T0, |
|
136 |
gen_op_movl_i5_T0, |
|
137 |
gen_op_movl_i6_T0, |
|
138 |
gen_op_movl_i7_T0, |
|
139 |
}, |
|
140 |
{ |
|
141 |
gen_op_movl_g0_T1, |
|
142 |
gen_op_movl_g1_T1, |
|
143 |
gen_op_movl_g2_T1, |
|
144 |
gen_op_movl_g3_T1, |
|
145 |
gen_op_movl_g4_T1, |
|
146 |
gen_op_movl_g5_T1, |
|
147 |
gen_op_movl_g6_T1, |
|
148 |
gen_op_movl_g7_T1, |
|
149 |
gen_op_movl_o0_T1, |
|
150 |
gen_op_movl_o1_T1, |
|
151 |
gen_op_movl_o2_T1, |
|
152 |
gen_op_movl_o3_T1, |
|
153 |
gen_op_movl_o4_T1, |
|
154 |
gen_op_movl_o5_T1, |
|
155 |
gen_op_movl_o6_T1, |
|
156 |
gen_op_movl_o7_T1, |
|
157 |
gen_op_movl_l0_T1, |
|
158 |
gen_op_movl_l1_T1, |
|
159 |
gen_op_movl_l2_T1, |
|
160 |
gen_op_movl_l3_T1, |
|
161 |
gen_op_movl_l4_T1, |
|
162 |
gen_op_movl_l5_T1, |
|
163 |
gen_op_movl_l6_T1, |
|
164 |
gen_op_movl_l7_T1, |
|
165 |
gen_op_movl_i0_T1, |
|
166 |
gen_op_movl_i1_T1, |
|
167 |
gen_op_movl_i2_T1, |
|
168 |
gen_op_movl_i3_T1, |
|
169 |
gen_op_movl_i4_T1, |
|
170 |
gen_op_movl_i5_T1, |
|
171 |
gen_op_movl_i6_T1, |
|
172 |
gen_op_movl_i7_T1, |
|
173 |
} |
|
174 |
}; |
|
175 |
|
|
176 |
static GenOpFunc * const gen_op_movl_reg_TN[3][32] = { |
|
177 |
{ |
|
178 |
gen_op_movl_T0_g0, |
|
179 |
gen_op_movl_T0_g1, |
|
180 |
gen_op_movl_T0_g2, |
|
181 |
gen_op_movl_T0_g3, |
|
182 |
gen_op_movl_T0_g4, |
|
183 |
gen_op_movl_T0_g5, |
|
184 |
gen_op_movl_T0_g6, |
|
185 |
gen_op_movl_T0_g7, |
|
186 |
gen_op_movl_T0_o0, |
|
187 |
gen_op_movl_T0_o1, |
|
188 |
gen_op_movl_T0_o2, |
|
189 |
gen_op_movl_T0_o3, |
|
190 |
gen_op_movl_T0_o4, |
|
191 |
gen_op_movl_T0_o5, |
|
192 |
gen_op_movl_T0_o6, |
|
193 |
gen_op_movl_T0_o7, |
|
194 |
gen_op_movl_T0_l0, |
|
195 |
gen_op_movl_T0_l1, |
|
196 |
gen_op_movl_T0_l2, |
|
197 |
gen_op_movl_T0_l3, |
|
198 |
gen_op_movl_T0_l4, |
|
199 |
gen_op_movl_T0_l5, |
|
200 |
gen_op_movl_T0_l6, |
|
201 |
gen_op_movl_T0_l7, |
|
202 |
gen_op_movl_T0_i0, |
|
203 |
gen_op_movl_T0_i1, |
|
204 |
gen_op_movl_T0_i2, |
|
205 |
gen_op_movl_T0_i3, |
|
206 |
gen_op_movl_T0_i4, |
|
207 |
gen_op_movl_T0_i5, |
|
208 |
gen_op_movl_T0_i6, |
|
209 |
gen_op_movl_T0_i7, |
|
210 |
}, |
|
211 |
{ |
|
212 |
gen_op_movl_T1_g0, |
|
213 |
gen_op_movl_T1_g1, |
|
214 |
gen_op_movl_T1_g2, |
|
215 |
gen_op_movl_T1_g3, |
|
216 |
gen_op_movl_T1_g4, |
|
217 |
gen_op_movl_T1_g5, |
|
218 |
gen_op_movl_T1_g6, |
|
219 |
gen_op_movl_T1_g7, |
|
220 |
gen_op_movl_T1_o0, |
|
221 |
gen_op_movl_T1_o1, |
|
222 |
gen_op_movl_T1_o2, |
|
223 |
gen_op_movl_T1_o3, |
|
224 |
gen_op_movl_T1_o4, |
|
225 |
gen_op_movl_T1_o5, |
|
226 |
gen_op_movl_T1_o6, |
|
227 |
gen_op_movl_T1_o7, |
|
228 |
gen_op_movl_T1_l0, |
|
229 |
gen_op_movl_T1_l1, |
|
230 |
gen_op_movl_T1_l2, |
|
231 |
gen_op_movl_T1_l3, |
|
232 |
gen_op_movl_T1_l4, |
|
233 |
gen_op_movl_T1_l5, |
|
234 |
gen_op_movl_T1_l6, |
|
235 |
gen_op_movl_T1_l7, |
|
236 |
gen_op_movl_T1_i0, |
|
237 |
gen_op_movl_T1_i1, |
|
238 |
gen_op_movl_T1_i2, |
|
239 |
gen_op_movl_T1_i3, |
|
240 |
gen_op_movl_T1_i4, |
|
241 |
gen_op_movl_T1_i5, |
|
242 |
gen_op_movl_T1_i6, |
|
243 |
gen_op_movl_T1_i7, |
|
244 |
}, |
|
245 |
{ |
|
246 |
gen_op_movl_T2_g0, |
|
247 |
gen_op_movl_T2_g1, |
|
248 |
gen_op_movl_T2_g2, |
|
249 |
gen_op_movl_T2_g3, |
|
250 |
gen_op_movl_T2_g4, |
|
251 |
gen_op_movl_T2_g5, |
|
252 |
gen_op_movl_T2_g6, |
|
253 |
gen_op_movl_T2_g7, |
|
254 |
gen_op_movl_T2_o0, |
|
255 |
gen_op_movl_T2_o1, |
|
256 |
gen_op_movl_T2_o2, |
|
257 |
gen_op_movl_T2_o3, |
|
258 |
gen_op_movl_T2_o4, |
|
259 |
gen_op_movl_T2_o5, |
|
260 |
gen_op_movl_T2_o6, |
|
261 |
gen_op_movl_T2_o7, |
|
262 |
gen_op_movl_T2_l0, |
|
263 |
gen_op_movl_T2_l1, |
|
264 |
gen_op_movl_T2_l2, |
|
265 |
gen_op_movl_T2_l3, |
|
266 |
gen_op_movl_T2_l4, |
|
267 |
gen_op_movl_T2_l5, |
|
268 |
gen_op_movl_T2_l6, |
|
269 |
gen_op_movl_T2_l7, |
|
270 |
gen_op_movl_T2_i0, |
|
271 |
gen_op_movl_T2_i1, |
|
272 |
gen_op_movl_T2_i2, |
|
273 |
gen_op_movl_T2_i3, |
|
274 |
gen_op_movl_T2_i4, |
|
275 |
gen_op_movl_T2_i5, |
|
276 |
gen_op_movl_T2_i6, |
|
277 |
gen_op_movl_T2_i7, |
|
278 |
} |
|
279 |
}; |
|
280 |
|
|
281 |
static GenOpFunc1 * const gen_op_movl_TN_im[3] = { |
|
282 |
gen_op_movl_T0_im, |
|
283 |
gen_op_movl_T1_im, |
|
284 |
gen_op_movl_T2_im |
|
285 |
}; |
|
286 |
|
|
287 |
// Sign extending version |
|
288 |
static GenOpFunc1 * const gen_op_movl_TN_sim[3] = { |
|
289 |
gen_op_movl_T0_sim, |
|
290 |
gen_op_movl_T1_sim, |
|
291 |
gen_op_movl_T2_sim |
|
292 |
}; |
|
293 |
|
|
294 | 111 |
#ifdef TARGET_SPARC64 |
295 | 112 |
#define GEN32(func, NAME) \ |
296 | 113 |
static GenOpFunc * const NAME ## _table [64] = { \ |
... | ... | |
375 | 192 |
#endif |
376 | 193 |
|
377 | 194 |
#ifndef CONFIG_USER_ONLY |
378 |
OP_LD_TABLE(ld); |
|
379 |
OP_LD_TABLE(st); |
|
380 |
OP_LD_TABLE(ldub); |
|
381 |
OP_LD_TABLE(lduh); |
|
382 |
OP_LD_TABLE(ldsb); |
|
383 |
OP_LD_TABLE(ldsh); |
|
384 |
OP_LD_TABLE(stb); |
|
385 |
OP_LD_TABLE(sth); |
|
386 |
OP_LD_TABLE(std); |
|
387 |
OP_LD_TABLE(ldstub); |
|
388 |
OP_LD_TABLE(swap); |
|
389 |
OP_LD_TABLE(ldd); |
|
390 | 195 |
OP_LD_TABLE(stf); |
391 | 196 |
OP_LD_TABLE(stdf); |
392 | 197 |
OP_LD_TABLE(ldf); |
393 | 198 |
OP_LD_TABLE(lddf); |
394 |
|
|
395 |
#ifdef TARGET_SPARC64 |
|
396 |
OP_LD_TABLE(lduw); |
|
397 |
OP_LD_TABLE(ldsw); |
|
398 |
OP_LD_TABLE(ldx); |
|
399 |
OP_LD_TABLE(stx); |
|
400 |
#endif |
|
401 | 199 |
#endif |
402 | 200 |
|
403 |
/* asi moves */ |
|
404 |
#ifdef TARGET_SPARC64 |
|
405 |
static inline void gen_ld_asi(int insn, int size, int sign) |
|
406 |
{ |
|
407 |
int asi, offset; |
|
408 |
|
|
409 |
if (IS_IMM) { |
|
410 |
offset = GET_FIELD(insn, 25, 31); |
|
411 |
gen_op_ld_asi_reg(offset, size, sign); |
|
412 |
} else { |
|
413 |
asi = GET_FIELD(insn, 19, 26); |
|
414 |
gen_op_ld_asi(asi, size, sign); |
|
415 |
} |
|
416 |
} |
|
417 |
|
|
418 |
static inline void gen_st_asi(int insn, int size) |
|
419 |
{ |
|
420 |
int asi, offset; |
|
421 |
|
|
422 |
if (IS_IMM) { |
|
423 |
offset = GET_FIELD(insn, 25, 31); |
|
424 |
gen_op_st_asi_reg(offset, size); |
|
425 |
} else { |
|
426 |
asi = GET_FIELD(insn, 19, 26); |
|
427 |
gen_op_st_asi(asi, size); |
|
428 |
} |
|
429 |
} |
|
430 |
|
|
431 |
static inline void gen_ldf_asi(int insn, int size, int rd) |
|
432 |
{ |
|
433 |
int asi, offset; |
|
434 |
|
|
435 |
if (IS_IMM) { |
|
436 |
offset = GET_FIELD(insn, 25, 31); |
|
437 |
gen_op_ldf_asi_reg(offset, size, rd); |
|
438 |
} else { |
|
439 |
asi = GET_FIELD(insn, 19, 26); |
|
440 |
gen_op_ldf_asi(asi, size, rd); |
|
441 |
} |
|
442 |
} |
|
443 |
|
|
444 |
static inline void gen_stf_asi(int insn, int size, int rd) |
|
445 |
{ |
|
446 |
int asi, offset; |
|
447 |
|
|
448 |
if (IS_IMM) { |
|
449 |
offset = GET_FIELD(insn, 25, 31); |
|
450 |
gen_op_stf_asi_reg(offset, size, rd); |
|
451 |
} else { |
|
452 |
asi = GET_FIELD(insn, 19, 26); |
|
453 |
gen_op_stf_asi(asi, size, rd); |
|
454 |
} |
|
455 |
} |
|
201 |
#ifdef TARGET_ABI32 |
|
202 |
#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffffULL); |
|
203 |
#else |
|
204 |
#define ABI32_MASK(addr) |
|
205 |
#endif |
|
456 | 206 |
|
457 |
static inline void gen_swap_asi(int insn)
|
|
207 |
static inline void gen_movl_simm_T1(int32_t val)
|
|
458 | 208 |
{ |
459 |
int asi, offset; |
|
460 |
|
|
461 |
if (IS_IMM) { |
|
462 |
offset = GET_FIELD(insn, 25, 31); |
|
463 |
gen_op_swap_asi_reg(offset); |
|
464 |
} else { |
|
465 |
asi = GET_FIELD(insn, 19, 26); |
|
466 |
gen_op_swap_asi(asi); |
|
467 |
} |
|
209 |
tcg_gen_movi_tl(cpu_T[1], val); |
|
468 | 210 |
} |
469 | 211 |
|
470 |
static inline void gen_ldstub_asi(int insn)
|
|
212 |
static inline void gen_movl_reg_TN(int reg, TCGv tn)
|
|
471 | 213 |
{ |
472 |
int asi, offset; |
|
473 |
|
|
474 |
if (IS_IMM) { |
|
475 |
offset = GET_FIELD(insn, 25, 31); |
|
476 |
gen_op_ldstub_asi_reg(offset); |
|
477 |
} else { |
|
478 |
asi = GET_FIELD(insn, 19, 26); |
|
479 |
gen_op_ldstub_asi(asi); |
|
214 |
if (reg == 0) |
|
215 |
tcg_gen_movi_tl(tn, 0); |
|
216 |
else if (reg < 8) |
|
217 |
tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUState, gregs[reg])); |
|
218 |
else { |
|
219 |
tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX |
|
220 |
tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong)); |
|
480 | 221 |
} |
481 | 222 |
} |
482 | 223 |
|
483 |
static inline void gen_ldda_asi(int insn)
|
|
224 |
static inline void gen_movl_reg_T0(int reg)
|
|
484 | 225 |
{ |
485 |
int asi, offset; |
|
486 |
|
|
487 |
if (IS_IMM) { |
|
488 |
offset = GET_FIELD(insn, 25, 31); |
|
489 |
gen_op_ldda_asi_reg(offset); |
|
490 |
} else { |
|
491 |
asi = GET_FIELD(insn, 19, 26); |
|
492 |
gen_op_ldda_asi(asi); |
|
493 |
} |
|
226 |
gen_movl_reg_TN(reg, cpu_T[0]); |
|
494 | 227 |
} |
495 | 228 |
|
496 |
static inline void gen_stda_asi(int insn)
|
|
229 |
static inline void gen_movl_reg_T1(int reg)
|
|
497 | 230 |
{ |
498 |
int asi, offset; |
|
499 |
|
|
500 |
if (IS_IMM) { |
|
501 |
offset = GET_FIELD(insn, 25, 31); |
|
502 |
gen_op_stda_asi_reg(offset); |
|
503 |
} else { |
|
504 |
asi = GET_FIELD(insn, 19, 26); |
|
505 |
gen_op_stda_asi(asi); |
|
506 |
} |
|
231 |
gen_movl_reg_TN(reg, cpu_T[1]); |
|
507 | 232 |
} |
508 | 233 |
|
509 |
static inline void gen_cas_asi(int insn)
|
|
234 |
static inline void gen_movl_TN_reg(int reg, TCGv tn)
|
|
510 | 235 |
{ |
511 |
int asi, offset; |
|
512 |
|
|
513 |
if (IS_IMM) { |
|
514 |
offset = GET_FIELD(insn, 25, 31); |
|
515 |
gen_op_cas_asi_reg(offset); |
|
516 |
} else { |
|
517 |
asi = GET_FIELD(insn, 19, 26); |
|
518 |
gen_op_cas_asi(asi); |
|
236 |
if (reg == 0) |
|
237 |
return; |
|
238 |
else if (reg < 8) |
|
239 |
tcg_gen_st_tl(tn, cpu_env, offsetof(CPUState, gregs[reg])); |
|
240 |
else { |
|
241 |
tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX |
|
242 |
tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong)); |
|
519 | 243 |
} |
520 | 244 |
} |
521 | 245 |
|
522 |
static inline void gen_casx_asi(int insn) |
|
523 |
{ |
|
524 |
int asi, offset; |
|
525 |
|
|
526 |
if (IS_IMM) { |
|
527 |
offset = GET_FIELD(insn, 25, 31); |
|
528 |
gen_op_casx_asi_reg(offset); |
|
529 |
} else { |
|
530 |
asi = GET_FIELD(insn, 19, 26); |
|
531 |
gen_op_casx_asi(asi); |
|
532 |
} |
|
533 |
} |
|
534 |
|
|
535 |
#elif !defined(CONFIG_USER_ONLY) |
|
536 |
|
|
537 |
static inline void gen_ld_asi(int insn, int size, int sign) |
|
538 |
{ |
|
539 |
int asi; |
|
540 |
|
|
541 |
asi = GET_FIELD(insn, 19, 26); |
|
542 |
gen_op_ld_asi(asi, size, sign); |
|
543 |
} |
|
544 |
|
|
545 |
static inline void gen_st_asi(int insn, int size) |
|
546 |
{ |
|
547 |
int asi; |
|
548 |
|
|
549 |
asi = GET_FIELD(insn, 19, 26); |
|
550 |
gen_op_st_asi(asi, size); |
|
551 |
} |
|
552 |
|
|
553 |
static inline void gen_ldstub_asi(int insn) |
|
554 |
{ |
|
555 |
int asi; |
|
556 |
|
|
557 |
asi = GET_FIELD(insn, 19, 26); |
|
558 |
gen_op_ldstub_asi(asi); |
|
559 |
} |
|
560 |
|
|
561 |
static inline void gen_swap_asi(int insn) |
|
562 |
{ |
|
563 |
int asi; |
|
564 |
|
|
565 |
asi = GET_FIELD(insn, 19, 26); |
|
566 |
gen_op_swap_asi(asi); |
|
567 |
} |
|
568 |
|
|
569 |
static inline void gen_ldda_asi(int insn) |
|
570 |
{ |
|
571 |
int asi; |
|
572 |
|
|
573 |
asi = GET_FIELD(insn, 19, 26); |
|
574 |
gen_op_ld_asi(asi, 8, 0); |
|
575 |
} |
|
576 |
|
|
577 |
static inline void gen_stda_asi(int insn) |
|
578 |
{ |
|
579 |
int asi; |
|
580 |
|
|
581 |
asi = GET_FIELD(insn, 19, 26); |
|
582 |
gen_op_st_asi(asi, 8); |
|
583 |
} |
|
584 |
#endif |
|
585 |
|
|
586 |
static inline void gen_movl_imm_TN(int reg, uint32_t imm) |
|
587 |
{ |
|
588 |
gen_op_movl_TN_im[reg](imm); |
|
589 |
} |
|
590 |
|
|
591 |
static inline void gen_movl_imm_T1(uint32_t val) |
|
592 |
{ |
|
593 |
gen_movl_imm_TN(1, val); |
|
594 |
} |
|
595 |
|
|
596 |
static inline void gen_movl_imm_T0(uint32_t val) |
|
597 |
{ |
|
598 |
gen_movl_imm_TN(0, val); |
|
599 |
} |
|
600 |
|
|
601 |
static inline void gen_movl_simm_TN(int reg, int32_t imm) |
|
602 |
{ |
|
603 |
gen_op_movl_TN_sim[reg](imm); |
|
604 |
} |
|
605 |
|
|
606 |
static inline void gen_movl_simm_T1(int32_t val) |
|
246 |
static inline void gen_movl_T0_reg(int reg) |
|
607 | 247 |
{ |
608 |
gen_movl_simm_TN(1, val);
|
|
248 |
gen_movl_TN_reg(reg, cpu_T[0]);
|
|
609 | 249 |
} |
610 | 250 |
|
611 |
static inline void gen_movl_simm_T0(int32_t val)
|
|
251 |
static inline void gen_movl_T1_reg(int reg)
|
|
612 | 252 |
{ |
613 |
gen_movl_simm_TN(0, val);
|
|
253 |
gen_movl_TN_reg(reg, cpu_T[1]);
|
|
614 | 254 |
} |
615 | 255 |
|
616 |
static inline void gen_movl_reg_TN(int reg, int t)
|
|
256 |
static inline void gen_op_movl_T0_env(size_t offset)
|
|
617 | 257 |
{ |
618 |
if (reg) |
|
619 |
gen_op_movl_reg_TN[t][reg] (); |
|
620 |
else |
|
621 |
gen_movl_imm_TN(t, 0); |
|
258 |
tcg_gen_ld_i32(cpu_T[0], cpu_env, offset); |
|
622 | 259 |
} |
623 | 260 |
|
624 |
static inline void gen_movl_reg_T0(int reg)
|
|
261 |
static inline void gen_op_movl_env_T0(size_t offset)
|
|
625 | 262 |
{ |
626 |
gen_movl_reg_TN(reg, 0);
|
|
263 |
tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
|
|
627 | 264 |
} |
628 | 265 |
|
629 |
static inline void gen_movl_reg_T1(int reg)
|
|
266 |
static inline void gen_op_movtl_T0_env(size_t offset)
|
|
630 | 267 |
{ |
631 |
gen_movl_reg_TN(reg, 1);
|
|
268 |
tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
|
|
632 | 269 |
} |
633 | 270 |
|
634 |
static inline void gen_movl_reg_T2(int reg)
|
|
271 |
static inline void gen_op_movtl_env_T0(size_t offset)
|
|
635 | 272 |
{ |
636 |
gen_movl_reg_TN(reg, 2);
|
|
273 |
tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
|
|
637 | 274 |
} |
638 | 275 |
|
639 |
static inline void gen_movl_TN_reg(int reg, int t)
|
|
276 |
static inline void gen_op_add_T1_T0(void)
|
|
640 | 277 |
{ |
641 |
if (reg) |
|
642 |
gen_op_movl_TN_reg[t][reg] (); |
|
278 |
tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
643 | 279 |
} |
644 | 280 |
|
645 |
static inline void gen_movl_T0_reg(int reg)
|
|
281 |
static inline void gen_op_or_T1_T0(void)
|
|
646 | 282 |
{ |
647 |
gen_movl_TN_reg(reg, 0);
|
|
283 |
tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
|
|
648 | 284 |
} |
649 | 285 |
|
650 |
static inline void gen_movl_T1_reg(int reg)
|
|
286 |
static inline void gen_op_xor_T1_T0(void)
|
|
651 | 287 |
{ |
652 |
gen_movl_TN_reg(reg, 1);
|
|
288 |
tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
|
|
653 | 289 |
} |
654 | 290 |
|
655 | 291 |
static inline void gen_jmp_im(target_ulong pc) |
656 | 292 |
{ |
657 |
#ifdef TARGET_SPARC64 |
|
658 |
if (pc == (uint32_t)pc) { |
|
659 |
gen_op_jmp_im(pc); |
|
660 |
} else { |
|
661 |
gen_op_jmp_im64(pc >> 32, pc); |
|
662 |
} |
|
663 |
#else |
|
664 |
gen_op_jmp_im(pc); |
|
665 |
#endif |
|
293 |
tcg_gen_movi_tl(cpu_tmp0, pc); |
|
294 |
tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, pc)); |
|
666 | 295 |
} |
667 | 296 |
|
668 | 297 |
static inline void gen_movl_npc_im(target_ulong npc) |
669 | 298 |
{ |
670 |
#ifdef TARGET_SPARC64 |
|
671 |
if (npc == (uint32_t)npc) { |
|
672 |
gen_op_movl_npc_im(npc); |
|
673 |
} else { |
|
674 |
gen_op_movq_npc_im64(npc >> 32, npc); |
|
675 |
} |
|
676 |
#else |
|
677 |
gen_op_movl_npc_im(npc); |
|
678 |
#endif |
|
299 |
tcg_gen_movi_tl(cpu_tmp0, npc); |
|
300 |
tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, npc)); |
|
679 | 301 |
} |
680 | 302 |
|
681 | 303 |
static inline void gen_goto_tb(DisasContext *s, int tb_num, |
... | ... | |
1095 | 717 |
return 0; |
1096 | 718 |
} |
1097 | 719 |
|
720 |
/* asi moves */ |
|
721 |
#ifdef TARGET_SPARC64 |
|
722 |
static inline void gen_ld_asi(int insn, int size, int sign) |
|
723 |
{ |
|
724 |
int asi, offset; |
|
725 |
TCGv r_size, r_sign; |
|
726 |
|
|
727 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
728 |
r_sign = tcg_temp_new(TCG_TYPE_I32); |
|
729 |
tcg_gen_movi_i32(r_size, size); |
|
730 |
tcg_gen_movi_i32(r_sign, sign); |
|
731 |
if (IS_IMM) { |
|
732 |
offset = GET_FIELD(insn, 25, 31); |
|
733 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
734 |
tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi)); |
|
735 |
} else { |
|
736 |
asi = GET_FIELD(insn, 19, 26); |
|
737 |
tcg_gen_movi_i32(cpu_T[1], asi); |
|
738 |
} |
|
739 |
tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], cpu_T[1], r_size, |
|
740 |
r_sign); |
|
741 |
} |
|
742 |
|
|
743 |
static inline void gen_st_asi(int insn, int size) |
|
744 |
{ |
|
745 |
int asi, offset; |
|
746 |
TCGv r_asi, r_size; |
|
747 |
|
|
748 |
r_asi = tcg_temp_new(TCG_TYPE_I32); |
|
749 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
750 |
tcg_gen_movi_i32(r_size, size); |
|
751 |
if (IS_IMM) { |
|
752 |
offset = GET_FIELD(insn, 25, 31); |
|
753 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
754 |
tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi)); |
|
755 |
} else { |
|
756 |
asi = GET_FIELD(insn, 19, 26); |
|
757 |
tcg_gen_movi_i32(r_asi, asi); |
|
758 |
} |
|
759 |
tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi, r_size); |
|
760 |
} |
|
761 |
|
|
762 |
static inline void gen_ldf_asi(int insn, int size, int rd) |
|
763 |
{ |
|
764 |
int asi, offset; |
|
765 |
TCGv r_asi, r_size, r_rd; |
|
766 |
|
|
767 |
r_asi = tcg_temp_new(TCG_TYPE_I32); |
|
768 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
769 |
r_rd = tcg_temp_new(TCG_TYPE_I32); |
|
770 |
tcg_gen_movi_i32(r_size, size); |
|
771 |
tcg_gen_movi_i32(r_rd, rd); |
|
772 |
if (IS_IMM) { |
|
773 |
offset = GET_FIELD(insn, 25, 31); |
|
774 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
775 |
tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi)); |
|
776 |
} else { |
|
777 |
asi = GET_FIELD(insn, 19, 26); |
|
778 |
tcg_gen_movi_i32(r_asi, asi); |
|
779 |
} |
|
780 |
tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, r_size, r_rd); |
|
781 |
} |
|
782 |
|
|
783 |
static inline void gen_stf_asi(int insn, int size, int rd) |
|
784 |
{ |
|
785 |
int asi, offset; |
|
786 |
TCGv r_asi, r_size, r_rd; |
|
787 |
|
|
788 |
r_asi = tcg_temp_new(TCG_TYPE_I32); |
|
789 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
790 |
r_rd = tcg_temp_new(TCG_TYPE_I32); |
|
791 |
tcg_gen_movi_i32(r_size, size); |
|
792 |
tcg_gen_movi_i32(r_rd, rd); |
|
793 |
if (IS_IMM) { |
|
794 |
offset = GET_FIELD(insn, 25, 31); |
|
795 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
796 |
tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi)); |
|
797 |
} else { |
|
798 |
asi = GET_FIELD(insn, 19, 26); |
|
799 |
tcg_gen_movi_i32(r_asi, asi); |
|
800 |
} |
|
801 |
tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, r_size, r_rd); |
|
802 |
} |
|
803 |
|
|
804 |
static inline void gen_swap_asi(int insn) |
|
805 |
{ |
|
806 |
int asi, offset; |
|
807 |
TCGv r_size, r_sign, r_temp; |
|
808 |
|
|
809 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
810 |
r_sign = tcg_temp_new(TCG_TYPE_I32); |
|
811 |
r_temp = tcg_temp_new(TCG_TYPE_I32); |
|
812 |
tcg_gen_movi_i32(r_size, 4); |
|
813 |
tcg_gen_movi_i32(r_sign, 0); |
|
814 |
if (IS_IMM) { |
|
815 |
offset = GET_FIELD(insn, 25, 31); |
|
816 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
817 |
tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi)); |
|
818 |
} else { |
|
819 |
asi = GET_FIELD(insn, 19, 26); |
|
820 |
tcg_gen_movi_i32(cpu_T[1], asi); |
|
821 |
} |
|
822 |
tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size, |
|
823 |
r_sign); |
|
824 |
tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign); |
|
825 |
tcg_gen_mov_i32(cpu_T[1], r_temp); |
|
826 |
} |
|
827 |
|
|
828 |
static inline void gen_ldda_asi(int insn) |
|
829 |
{ |
|
830 |
int asi, offset; |
|
831 |
TCGv r_size, r_sign, r_dword; |
|
832 |
|
|
833 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
834 |
r_sign = tcg_temp_new(TCG_TYPE_I32); |
|
835 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
836 |
tcg_gen_movi_i32(r_size, 8); |
|
837 |
tcg_gen_movi_i32(r_sign, 0); |
|
838 |
if (IS_IMM) { |
|
839 |
offset = GET_FIELD(insn, 25, 31); |
|
840 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
841 |
tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi)); |
|
842 |
} else { |
|
843 |
asi = GET_FIELD(insn, 19, 26); |
|
844 |
tcg_gen_movi_i32(cpu_T[1], asi); |
|
845 |
} |
|
846 |
tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size, |
|
847 |
r_sign); |
|
848 |
tcg_gen_trunc_i64_i32(cpu_T[0], r_dword); |
|
849 |
tcg_gen_shri_i64(r_dword, r_dword, 32); |
|
850 |
tcg_gen_trunc_i64_i32(cpu_T[1], r_dword); |
|
851 |
} |
|
852 |
|
|
853 |
static inline void gen_cas_asi(int insn, int rd) |
|
854 |
{ |
|
855 |
int asi, offset; |
|
856 |
TCGv r_val1, r_asi; |
|
857 |
|
|
858 |
r_val1 = tcg_temp_new(TCG_TYPE_I32); |
|
859 |
r_asi = tcg_temp_new(TCG_TYPE_I32); |
|
860 |
gen_movl_reg_TN(rd, r_val1); |
|
861 |
if (IS_IMM) { |
|
862 |
offset = GET_FIELD(insn, 25, 31); |
|
863 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
864 |
tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi)); |
|
865 |
} else { |
|
866 |
asi = GET_FIELD(insn, 19, 26); |
|
867 |
tcg_gen_movi_i32(r_asi, asi); |
|
868 |
} |
|
869 |
tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1], |
|
870 |
r_asi); |
|
871 |
} |
|
872 |
|
|
873 |
static inline void gen_casx_asi(int insn, int rd) |
|
874 |
{ |
|
875 |
int asi, offset; |
|
876 |
TCGv r_val1, r_asi; |
|
877 |
|
|
878 |
r_val1 = tcg_temp_new(TCG_TYPE_I64); |
|
879 |
r_asi = tcg_temp_new(TCG_TYPE_I32); |
|
880 |
gen_movl_reg_TN(rd, r_val1); |
|
881 |
if (IS_IMM) { |
|
882 |
offset = GET_FIELD(insn, 25, 31); |
|
883 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
884 |
tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi)); |
|
885 |
} else { |
|
886 |
asi = GET_FIELD(insn, 19, 26); |
|
887 |
tcg_gen_movi_i32(r_asi, asi); |
|
888 |
} |
|
889 |
tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1], |
|
890 |
r_asi); |
|
891 |
} |
|
892 |
|
|
893 |
#elif !defined(CONFIG_USER_ONLY) |
|
894 |
|
|
895 |
static inline void gen_ld_asi(int insn, int size, int sign) |
|
896 |
{ |
|
897 |
int asi; |
|
898 |
TCGv r_size, r_sign, r_dword; |
|
899 |
|
|
900 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
901 |
r_sign = tcg_temp_new(TCG_TYPE_I32); |
|
902 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
903 |
tcg_gen_movi_i32(r_size, size); |
|
904 |
tcg_gen_movi_i32(r_sign, sign); |
|
905 |
asi = GET_FIELD(insn, 19, 26); |
|
906 |
tcg_gen_movi_i32(cpu_T[1], asi); |
|
907 |
tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size, |
|
908 |
r_sign); |
|
909 |
tcg_gen_trunc_i64_i32(cpu_T[1], r_dword); |
|
910 |
} |
|
911 |
|
|
912 |
static inline void gen_st_asi(int insn, int size) |
|
913 |
{ |
|
914 |
int asi; |
|
915 |
TCGv r_dword, r_asi, r_size; |
|
916 |
|
|
917 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
918 |
tcg_gen_extu_i32_i64(r_dword, cpu_T[1]); |
|
919 |
r_asi = tcg_temp_new(TCG_TYPE_I32); |
|
920 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
921 |
asi = GET_FIELD(insn, 19, 26); |
|
922 |
tcg_gen_movi_i32(r_asi, asi); |
|
923 |
tcg_gen_movi_i32(r_size, size); |
|
924 |
tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size); |
|
925 |
} |
|
926 |
|
|
927 |
static inline void gen_swap_asi(int insn) |
|
928 |
{ |
|
929 |
int asi; |
|
930 |
TCGv r_size, r_sign, r_temp; |
|
931 |
|
|
932 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
933 |
r_sign = tcg_temp_new(TCG_TYPE_I32); |
|
934 |
r_temp = tcg_temp_new(TCG_TYPE_I32); |
|
935 |
tcg_gen_movi_i32(r_size, 4); |
|
936 |
tcg_gen_movi_i32(r_sign, 0); |
|
937 |
asi = GET_FIELD(insn, 19, 26); |
|
938 |
tcg_gen_movi_i32(cpu_T[1], asi); |
|
939 |
tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size, |
|
940 |
r_sign); |
|
941 |
tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign); |
|
942 |
tcg_gen_mov_i32(cpu_T[1], r_temp); |
|
943 |
} |
|
944 |
|
|
945 |
static inline void gen_ldda_asi(int insn) |
|
946 |
{ |
|
947 |
int asi; |
|
948 |
TCGv r_size, r_sign, r_dword; |
|
949 |
|
|
950 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
951 |
r_sign = tcg_temp_new(TCG_TYPE_I32); |
|
952 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
953 |
tcg_gen_movi_i32(r_size, 8); |
|
954 |
tcg_gen_movi_i32(r_sign, 0); |
|
955 |
asi = GET_FIELD(insn, 19, 26); |
|
956 |
tcg_gen_movi_i32(cpu_T[1], asi); |
|
957 |
tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size, |
|
958 |
r_sign); |
|
959 |
tcg_gen_trunc_i64_i32(cpu_T[0], r_dword); |
|
960 |
tcg_gen_shri_i64(r_dword, r_dword, 32); |
|
961 |
tcg_gen_trunc_i64_i32(cpu_T[1], r_dword); |
|
962 |
} |
|
963 |
#endif |
|
964 |
|
|
965 |
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) |
|
966 |
static inline void gen_ldstub_asi(int insn) |
|
967 |
{ |
|
968 |
int asi; |
|
969 |
TCGv r_dword, r_asi, r_size; |
|
970 |
|
|
971 |
gen_ld_asi(insn, 1, 0); |
|
972 |
|
|
973 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
974 |
r_asi = tcg_temp_new(TCG_TYPE_I32); |
|
975 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
976 |
asi = GET_FIELD(insn, 19, 26); |
|
977 |
tcg_gen_movi_i32(r_dword, 0xff); |
|
978 |
tcg_gen_movi_i32(r_asi, asi); |
|
979 |
tcg_gen_movi_i32(r_size, 1); |
|
980 |
tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size); |
|
981 |
} |
|
982 |
#endif |
|
983 |
|
|
1098 | 984 |
/* before an instruction, dc->pc must be static */ |
1099 | 985 |
static void disas_sparc_insn(DisasContext * dc) |
1100 | 986 |
{ |
... | ... | |
1179 | 1065 |
if (rd) { // nop |
1180 | 1066 |
#endif |
1181 | 1067 |
uint32_t value = GET_FIELD(insn, 10, 31); |
1182 |
gen_movl_imm_T0(value << 10);
|
|
1068 |
tcg_gen_movi_tl(cpu_T[0], value << 10);
|
|
1183 | 1069 |
gen_movl_T0_reg(rd); |
1184 | 1070 |
#if defined(OPTIM) |
1185 | 1071 |
} |
... | ... | |
1196 | 1082 |
/*CALL*/ { |
1197 | 1083 |
target_long target = GET_FIELDs(insn, 2, 31) << 2; |
1198 | 1084 |
|
1199 |
#ifdef TARGET_SPARC64 |
|
1200 |
if (dc->pc == (uint32_t)dc->pc) { |
|
1201 |
gen_op_movl_T0_im(dc->pc); |
|
1202 |
} else { |
|
1203 |
gen_op_movq_T0_im64(dc->pc >> 32, dc->pc); |
|
1204 |
} |
|
1205 |
#else |
|
1206 |
gen_op_movl_T0_im(dc->pc); |
|
1207 |
#endif |
|
1085 |
tcg_gen_movi_tl(cpu_T[0], dc->pc); |
|
1208 | 1086 |
gen_movl_T0_reg(15); |
1209 | 1087 |
target += dc->pc; |
1210 | 1088 |
gen_mov_pc_npc(dc); |
... | ... | |
1221 | 1099 |
gen_movl_reg_T0(rs1); |
1222 | 1100 |
if (IS_IMM) { |
1223 | 1101 |
rs2 = GET_FIELD(insn, 25, 31); |
1224 |
#if defined(OPTIM) |
|
1225 |
if (rs2 != 0) { |
|
1226 |
#endif |
|
1227 |
gen_movl_simm_T1(rs2); |
|
1228 |
gen_op_add_T1_T0(); |
|
1229 |
#if defined(OPTIM) |
|
1230 |
} |
|
1231 |
#endif |
|
1102 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2); |
|
1232 | 1103 |
} else { |
1233 | 1104 |
rs2 = GET_FIELD(insn, 27, 31); |
1234 | 1105 |
#if defined(OPTIM) |
... | ... | |
1243 | 1114 |
cond = GET_FIELD(insn, 3, 6); |
1244 | 1115 |
if (cond == 0x8) { |
1245 | 1116 |
save_state(dc); |
1246 |
gen_op_trap_T0();
|
|
1117 |
tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
|
|
1247 | 1118 |
} else if (cond != 0) { |
1248 | 1119 |
#ifdef TARGET_SPARC64 |
1249 | 1120 |
/* V9 icc/xcc */ |
... | ... | |
1261 | 1132 |
save_state(dc); |
1262 | 1133 |
gen_cond[0][cond](); |
1263 | 1134 |
#endif |
1264 |
gen_op_trapcc_T0();
|
|
1135 |
tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], cpu_T[2]);
|
|
1265 | 1136 |
} |
1266 | 1137 |
gen_op_next_insn(); |
1267 | 1138 |
tcg_gen_exit_tb(0); |
... | ... | |
1298 | 1169 |
gen_movl_T0_reg(rd); |
1299 | 1170 |
break; |
1300 | 1171 |
case 0x5: /* V9 rdpc */ |
1301 |
if (dc->pc == (uint32_t)dc->pc) { |
|
1302 |
gen_op_movl_T0_im(dc->pc); |
|
1303 |
} else { |
|
1304 |
gen_op_movq_T0_im64(dc->pc >> 32, dc->pc); |
|
1305 |
} |
|
1172 |
tcg_gen_movi_tl(cpu_T[0], dc->pc); |
|
1306 | 1173 |
gen_movl_T0_reg(rd); |
1307 | 1174 |
break; |
1308 | 1175 |
case 0x6: /* V9 rdfprs */ |
... | ... | |
1344 | 1211 |
#ifndef TARGET_SPARC64 |
1345 | 1212 |
if (!supervisor(dc)) |
1346 | 1213 |
goto priv_insn; |
1347 |
gen_op_rdpsr();
|
|
1214 |
tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
|
|
1348 | 1215 |
#else |
1349 | 1216 |
if (!hypervisor(dc)) |
1350 | 1217 |
goto priv_insn; |
... | ... | |
1399 | 1266 |
gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr)); |
1400 | 1267 |
break; |
1401 | 1268 |
case 6: // pstate |
1402 |
gen_op_rdpstate();
|
|
1269 |
gen_op_movl_T0_env(offsetof(CPUSPARCState, pstate));
|
|
1403 | 1270 |
break; |
1404 | 1271 |
case 7: // tl |
1405 | 1272 |
gen_op_movl_T0_env(offsetof(CPUSPARCState, tl)); |
... | ... | |
2078 | 1945 |
|
2079 | 1946 |
rs1 = GET_FIELD(insn, 13, 17); |
2080 | 1947 |
if (rs1 == 0) { |
2081 |
// or %g0, x, y -> mov T1, x; mov y, T1
|
|
1948 |
// or %g0, x, y -> mov T0, x; mov y, T0
|
|
2082 | 1949 |
if (IS_IMM) { /* immediate */ |
2083 | 1950 |
rs2 = GET_FIELDs(insn, 19, 31); |
2084 |
gen_movl_simm_T1(rs2);
|
|
1951 |
tcg_gen_movi_tl(cpu_T[0], (int)rs2);
|
|
2085 | 1952 |
} else { /* register */ |
2086 | 1953 |
rs2 = GET_FIELD(insn, 27, 31); |
2087 |
gen_movl_reg_T1(rs2);
|
|
1954 |
gen_movl_reg_T0(rs2);
|
|
2088 | 1955 |
} |
2089 |
gen_movl_T1_reg(rd); |
|
2090 | 1956 |
} else { |
2091 | 1957 |
gen_movl_reg_T0(rs1); |
2092 | 1958 |
if (IS_IMM) { /* immediate */ |
2093 |
// or x, #0, y -> mov T1, x; mov y, T1 |
|
2094 | 1959 |
rs2 = GET_FIELDs(insn, 19, 31); |
2095 |
if (rs2 != 0) { |
|
2096 |
gen_movl_simm_T1(rs2); |
|
2097 |
gen_op_or_T1_T0(); |
|
2098 |
} |
|
1960 |
tcg_gen_ori_tl(cpu_T[0], cpu_T[0], (int)rs2); |
|
2099 | 1961 |
} else { /* register */ |
2100 | 1962 |
// or x, %g0, y -> mov T1, x; mov y, T1 |
2101 | 1963 |
rs2 = GET_FIELD(insn, 27, 31); |
... | ... | |
2104 | 1966 |
gen_op_or_T1_T0(); |
2105 | 1967 |
} |
2106 | 1968 |
} |
2107 |
gen_movl_T0_reg(rd); |
|
2108 | 1969 |
} |
1970 |
gen_movl_T0_reg(rd); |
|
2109 | 1971 |
#endif |
2110 | 1972 |
#ifdef TARGET_SPARC64 |
2111 | 1973 |
} else if (xop == 0x25) { /* sll, V9 sllx */ |
... | ... | |
2113 | 1975 |
gen_movl_reg_T0(rs1); |
2114 | 1976 |
if (IS_IMM) { /* immediate */ |
2115 | 1977 |
rs2 = GET_FIELDs(insn, 20, 31); |
2116 |
gen_movl_simm_T1(rs2); |
|
1978 |
if (insn & (1 << 12)) { |
|
1979 |
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f); |
|
1980 |
} else { |
|
1981 |
tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL); |
|
1982 |
tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f); |
|
1983 |
} |
|
2117 | 1984 |
} else { /* register */ |
2118 | 1985 |
rs2 = GET_FIELD(insn, 27, 31); |
2119 | 1986 |
gen_movl_reg_T1(rs2); |
1987 |
if (insn & (1 << 12)) { |
|
1988 |
tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f); |
|
1989 |
tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
1990 |
} else { |
|
1991 |
tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f); |
|
1992 |
tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL); |
|
1993 |
tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
1994 |
} |
|
2120 | 1995 |
} |
2121 |
if (insn & (1 << 12)) |
|
2122 |
gen_op_sllx(); |
|
2123 |
else |
|
2124 |
gen_op_sll(); |
|
2125 | 1996 |
gen_movl_T0_reg(rd); |
2126 | 1997 |
} else if (xop == 0x26) { /* srl, V9 srlx */ |
2127 | 1998 |
rs1 = GET_FIELD(insn, 13, 17); |
2128 | 1999 |
gen_movl_reg_T0(rs1); |
2129 | 2000 |
if (IS_IMM) { /* immediate */ |
2130 | 2001 |
rs2 = GET_FIELDs(insn, 20, 31); |
2131 |
gen_movl_simm_T1(rs2); |
|
2002 |
if (insn & (1 << 12)) { |
|
2003 |
tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f); |
|
2004 |
} else { |
|
2005 |
tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL); |
|
2006 |
tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f); |
|
2007 |
} |
|
2132 | 2008 |
} else { /* register */ |
2133 | 2009 |
rs2 = GET_FIELD(insn, 27, 31); |
2134 | 2010 |
gen_movl_reg_T1(rs2); |
2011 |
if (insn & (1 << 12)) { |
|
2012 |
tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f); |
|
2013 |
tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
2014 |
} else { |
|
2015 |
tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f); |
|
2016 |
tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL); |
|
2017 |
tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
2018 |
} |
|
2135 | 2019 |
} |
2136 |
if (insn & (1 << 12)) |
|
2137 |
gen_op_srlx(); |
|
2138 |
else |
|
2139 |
gen_op_srl(); |
|
2140 | 2020 |
gen_movl_T0_reg(rd); |
2141 | 2021 |
} else if (xop == 0x27) { /* sra, V9 srax */ |
2142 | 2022 |
rs1 = GET_FIELD(insn, 13, 17); |
2143 | 2023 |
gen_movl_reg_T0(rs1); |
2144 | 2024 |
if (IS_IMM) { /* immediate */ |
2145 | 2025 |
rs2 = GET_FIELDs(insn, 20, 31); |
2146 |
gen_movl_simm_T1(rs2); |
|
2026 |
if (insn & (1 << 12)) { |
|
2027 |
tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f); |
|
2028 |
} else { |
|
2029 |
tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL); |
|
2030 |
tcg_gen_ext_i32_i64(cpu_T[0], cpu_T[0]); |
|
2031 |
tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f); |
|
2032 |
} |
|
2147 | 2033 |
} else { /* register */ |
2148 | 2034 |
rs2 = GET_FIELD(insn, 27, 31); |
2149 | 2035 |
gen_movl_reg_T1(rs2); |
2036 |
if (insn & (1 << 12)) { |
|
2037 |
tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f); |
|
2038 |
tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
2039 |
} else { |
|
2040 |
tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f); |
|
2041 |
tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL); |
|
2042 |
tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
2043 |
} |
|
2150 | 2044 |
} |
2151 |
if (insn & (1 << 12)) |
|
2152 |
gen_op_srax(); |
|
2153 |
else |
|
2154 |
gen_op_sra(); |
|
2155 | 2045 |
gen_movl_T0_reg(rd); |
2156 | 2046 |
#endif |
2157 | 2047 |
} else if (xop < 0x36) { |
... | ... | |
2173 | 2063 |
gen_op_add_T1_T0(); |
2174 | 2064 |
break; |
2175 | 2065 |
case 0x1: |
2176 |
gen_op_and_T1_T0();
|
|
2066 |
tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
|
|
2177 | 2067 |
if (xop & 0x10) |
2178 | 2068 |
gen_op_logic_T0_cc(); |
2179 | 2069 |
break; |
2180 | 2070 |
case 0x2: |
2181 |
gen_op_or_T1_T0();
|
|
2071 |
tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
|
|
2182 | 2072 |
if (xop & 0x10) |
2183 | 2073 |
gen_op_logic_T0_cc(); |
2184 | 2074 |
break; |
2185 | 2075 |
case 0x3: |
2186 |
gen_op_xor_T1_T0();
|
|
2076 |
tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
|
|
2187 | 2077 |
if (xop & 0x10) |
2188 | 2078 |
gen_op_logic_T0_cc(); |
2189 | 2079 |
break; |
... | ... | |
2191 | 2081 |
if (xop & 0x10) |
2192 | 2082 |
gen_op_sub_T1_T0_cc(); |
2193 | 2083 |
else |
2194 |
gen_op_sub_T1_T0();
|
|
2084 |
tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
|
|
2195 | 2085 |
break; |
2196 | 2086 |
case 0x5: |
2197 | 2087 |
gen_op_andn_T1_T0(); |
... | ... | |
2216 | 2106 |
break; |
2217 | 2107 |
#ifdef TARGET_SPARC64 |
2218 | 2108 |
case 0x9: /* V9 mulx */ |
2219 |
gen_op_mulx_T1_T0();
|
|
2109 |
tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
|
|
2220 | 2110 |
break; |
2221 | 2111 |
#endif |
2222 | 2112 |
case 0xa: |
... | ... | |
2280 | 2170 |
break; |
2281 | 2171 |
#ifndef TARGET_SPARC64 |
2282 | 2172 |
case 0x25: /* sll */ |
2283 |
gen_op_sll(); |
|
2173 |
tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f); |
|
2174 |
tcg_gen_shl_i32(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
2284 | 2175 |
gen_movl_T0_reg(rd); |
2285 | 2176 |
break; |
2286 | 2177 |
case 0x26: /* srl */ |
2287 |
gen_op_srl(); |
|
2178 |
tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f); |
|
2179 |
tcg_gen_shr_i32(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
2288 | 2180 |
gen_movl_T0_reg(rd); |
2289 | 2181 |
break; |
2290 | 2182 |
case 0x27: /* sra */ |
2291 |
gen_op_sra(); |
|
2183 |
tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f); |
|
2184 |
tcg_gen_sar_i32(cpu_T[0], cpu_T[0], cpu_T[1]); |
|
2292 | 2185 |
gen_movl_T0_reg(rd); |
2293 | 2186 |
break; |
2294 | 2187 |
#endif |
... | ... | |
2329 | 2222 |
case 0xf: /* V9 sir, nop if user */ |
2330 | 2223 |
#if !defined(CONFIG_USER_ONLY) |
2331 | 2224 |
if (supervisor(dc)) |
2332 |
gen_op_sir();
|
|
2225 |
; // XXX
|
|
2333 | 2226 |
#endif |
2334 | 2227 |
break; |
2335 | 2228 |
case 0x13: /* Graphics Status */ |
... | ... | |
2400 | 2293 |
} |
2401 | 2294 |
#else |
2402 | 2295 |
gen_op_xor_T1_T0(); |
2403 |
gen_op_wrpsr();
|
|
2296 |
tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
|
|
2404 | 2297 |
save_state(dc); |
2405 | 2298 |
gen_op_next_insn(); |
2406 | 2299 |
tcg_gen_exit_tb(0); |
... | ... | |
2434 | 2327 |
gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr)); |
2435 | 2328 |
break; |
2436 | 2329 |
case 6: // pstate |
2437 |
gen_op_wrpstate(); |
|
2438 | 2330 |
save_state(dc); |
2331 |
tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]); |
|
2439 | 2332 |
gen_op_next_insn(); |
2440 | 2333 |
tcg_gen_exit_tb(0); |
2441 | 2334 |
dc->is_br = 1; |
... | ... | |
2476 | 2369 |
goto illegal_insn; |
2477 | 2370 |
} |
2478 | 2371 |
#else |
2479 |
gen_op_wrwim(); |
|
2372 |
tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1)); |
|
2373 |
gen_op_movl_env_T0(offsetof(CPUSPARCState, wim)); |
|
2480 | 2374 |
#endif |
2481 | 2375 |
} |
2482 | 2376 |
break; |
... | ... | |
2564 | 2458 |
rs2 = GET_FIELD_SP(insn, 0, 4); |
2565 | 2459 |
gen_movl_reg_T1(rs2); |
2566 | 2460 |
} |
2567 |
gen_op_popc(); |
|
2461 |
tcg_gen_helper_1_1(helper_popc, cpu_T[0], |
|
2462 |
cpu_T[1]); |
|
2568 | 2463 |
gen_movl_T0_reg(rd); |
2569 | 2464 |
} |
2570 | 2465 |
case 0x2f: /* V9 movr */ |
... | ... | |
3003 | 2898 |
gen_movl_reg_T0(rs1); |
3004 | 2899 |
if (IS_IMM) { /* immediate */ |
3005 | 2900 |
rs2 = GET_FIELDs(insn, 19, 31); |
3006 |
#if defined(OPTIM) |
|
3007 |
if (rs2) { |
|
3008 |
#endif |
|
3009 |
gen_movl_simm_T1(rs2); |
|
3010 |
gen_op_add_T1_T0(); |
|
3011 |
#if defined(OPTIM) |
|
3012 |
} |
|
3013 |
#endif |
|
2901 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2); |
|
3014 | 2902 |
} else { /* register */ |
3015 | 2903 |
rs2 = GET_FIELD(insn, 27, 31); |
3016 | 2904 |
#if defined(OPTIM) |
... | ... | |
3025 | 2913 |
gen_op_restore(); |
3026 | 2914 |
gen_mov_pc_npc(dc); |
3027 | 2915 |
gen_op_check_align_T0_3(); |
3028 |
gen_op_movl_npc_T0();
|
|
2916 |
tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
|
|
3029 | 2917 |
dc->npc = DYNAMIC_PC; |
3030 | 2918 |
goto jmp_insn; |
3031 | 2919 |
#endif |
... | ... | |
3034 | 2922 |
gen_movl_reg_T0(rs1); |
3035 | 2923 |
if (IS_IMM) { /* immediate */ |
3036 | 2924 |
rs2 = GET_FIELDs(insn, 19, 31); |
3037 |
#if defined(OPTIM) |
|
3038 |
if (rs2) { |
|
3039 |
#endif |
|
3040 |
gen_movl_simm_T1(rs2); |
|
3041 |
gen_op_add_T1_T0(); |
|
3042 |
#if defined(OPTIM) |
|
3043 |
} |
|
3044 |
#endif |
|
2925 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2); |
|
3045 | 2926 |
} else { /* register */ |
3046 | 2927 |
rs2 = GET_FIELD(insn, 27, 31); |
3047 | 2928 |
#if defined(OPTIM) |
... | ... | |
3057 | 2938 |
case 0x38: /* jmpl */ |
3058 | 2939 |
{ |
3059 | 2940 |
if (rd != 0) { |
3060 |
#ifdef TARGET_SPARC64 |
|
3061 |
if (dc->pc == (uint32_t)dc->pc) { |
|
3062 |
gen_op_movl_T1_im(dc->pc); |
|
3063 |
} else { |
|
3064 |
gen_op_movq_T1_im64(dc->pc >> 32, dc->pc); |
|
3065 |
} |
|
3066 |
#else |
|
3067 |
gen_op_movl_T1_im(dc->pc); |
|
3068 |
#endif |
|
2941 |
tcg_gen_movi_tl(cpu_T[1], dc->pc); |
|
3069 | 2942 |
gen_movl_T1_reg(rd); |
3070 | 2943 |
} |
3071 | 2944 |
gen_mov_pc_npc(dc); |
3072 | 2945 |
gen_op_check_align_T0_3(); |
3073 |
gen_op_movl_npc_T0();
|
|
2946 |
tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
|
|
3074 | 2947 |
dc->npc = DYNAMIC_PC; |
3075 | 2948 |
} |
3076 | 2949 |
goto jmp_insn; |
... | ... | |
3081 | 2954 |
goto priv_insn; |
3082 | 2955 |
gen_mov_pc_npc(dc); |
3083 | 2956 |
gen_op_check_align_T0_3(); |
3084 |
gen_op_movl_npc_T0();
|
|
2957 |
tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
|
|
3085 | 2958 |
dc->npc = DYNAMIC_PC; |
3086 |
gen_op_rett();
|
|
2959 |
tcg_gen_helper_0_0(helper_rett);
|
|
3087 | 2960 |
} |
3088 | 2961 |
goto jmp_insn; |
3089 | 2962 |
#endif |
3090 | 2963 |
case 0x3b: /* flush */ |
3091 |
gen_op_flush_T0();
|
|
2964 |
tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
|
|
3092 | 2965 |
break; |
3093 | 2966 |
case 0x3c: /* save */ |
3094 | 2967 |
save_state(dc); |
... | ... | |
3109 | 2982 |
goto priv_insn; |
3110 | 2983 |
dc->npc = DYNAMIC_PC; |
3111 | 2984 |
dc->pc = DYNAMIC_PC; |
3112 |
gen_op_done();
|
|
2985 |
tcg_gen_helper_0_0(helper_done);
|
|
3113 | 2986 |
goto jmp_insn; |
3114 | 2987 |
case 1: |
3115 | 2988 |
if (!supervisor(dc)) |
3116 | 2989 |
goto priv_insn; |
3117 | 2990 |
dc->npc = DYNAMIC_PC; |
3118 | 2991 |
dc->pc = DYNAMIC_PC; |
3119 |
gen_op_retry();
|
|
2992 |
tcg_gen_helper_0_0(helper_retry);
|
|
3120 | 2993 |
goto jmp_insn; |
3121 | 2994 |
default: |
3122 | 2995 |
goto illegal_insn; |
... | ... | |
3144 | 3017 |
} |
3145 | 3018 |
else if (IS_IMM) { /* immediate */ |
3146 | 3019 |
rs2 = GET_FIELDs(insn, 19, 31); |
3147 |
#if defined(OPTIM) |
|
3148 |
if (rs2 != 0) { |
|
3149 |
#endif |
|
3150 |
gen_movl_simm_T1(rs2); |
|
3151 |
gen_op_add_T1_T0(); |
|
3152 |
#if defined(OPTIM) |
|
3153 |
} |
|
3154 |
#endif |
|
3020 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2); |
|
3155 | 3021 |
} else { /* register */ |
3156 | 3022 |
rs2 = GET_FIELD(insn, 27, 31); |
3157 | 3023 |
#if defined(OPTIM) |
... | ... | |
3167 | 3033 |
(xop > 0x17 && xop <= 0x1d ) || |
3168 | 3034 |
(xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) { |
3169 | 3035 |
switch (xop) { |
3170 |
case 0x0: /* load word */ |
|
3036 |
case 0x0: /* load unsigned word */
|
|
3171 | 3037 |
gen_op_check_align_T0_3(); |
3172 |
#ifndef TARGET_SPARC64 |
|
3173 |
gen_op_ldst(ld); |
|
3174 |
#else |
|
3175 |
gen_op_ldst(lduw); |
|
3176 |
#endif |
|
3038 |
ABI32_MASK(cpu_T[0]); |
|
3039 |
tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3177 | 3040 |
break; |
3178 | 3041 |
case 0x1: /* load unsigned byte */ |
3179 |
gen_op_ldst(ldub); |
|
3042 |
ABI32_MASK(cpu_T[0]); |
|
3043 |
tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3180 | 3044 |
break; |
3181 | 3045 |
case 0x2: /* load unsigned halfword */ |
3182 | 3046 |
gen_op_check_align_T0_1(); |
3183 |
gen_op_ldst(lduh); |
|
3047 |
ABI32_MASK(cpu_T[0]); |
|
3048 |
tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3184 | 3049 |
break; |
3185 | 3050 |
case 0x3: /* load double word */ |
3186 | 3051 |
if (rd & 1) |
3187 | 3052 |
goto illegal_insn; |
3188 |
gen_op_check_align_T0_7(); |
|
3189 |
gen_op_ldst(ldd); |
|
3190 |
gen_movl_T0_reg(rd + 1); |
|
3053 |
else { |
|
3054 |
TCGv r_dword; |
|
3055 |
|
|
3056 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
3057 |
gen_op_check_align_T0_7(); |
|
3058 |
ABI32_MASK(cpu_T[0]); |
|
3059 |
tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx); |
|
3060 |
tcg_gen_trunc_i64_i32(cpu_T[0], r_dword); |
|
3061 |
gen_movl_T0_reg(rd + 1); |
|
3062 |
tcg_gen_shri_i64(r_dword, r_dword, 32); |
|
3063 |
tcg_gen_trunc_i64_i32(cpu_T[1], r_dword); |
|
3064 |
} |
|
3191 | 3065 |
break; |
3192 | 3066 |
case 0x9: /* load signed byte */ |
3193 |
gen_op_ldst(ldsb); |
|
3067 |
ABI32_MASK(cpu_T[0]); |
|
3068 |
tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3194 | 3069 |
break; |
3195 | 3070 |
case 0xa: /* load signed halfword */ |
3196 | 3071 |
gen_op_check_align_T0_1(); |
3197 |
gen_op_ldst(ldsh); |
|
3072 |
ABI32_MASK(cpu_T[0]); |
|
3073 |
tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3198 | 3074 |
break; |
3199 | 3075 |
case 0xd: /* ldstub -- XXX: should be atomically */ |
3200 |
gen_op_ldst(ldstub); |
|
3076 |
tcg_gen_movi_i32(cpu_tmp0, 0xff); |
|
3077 |
ABI32_MASK(cpu_T[0]); |
|
3078 |
tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3079 |
tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx); |
|
3201 | 3080 |
break; |
3202 | 3081 |
case 0x0f: /* swap register with memory. Also atomically */ |
3203 | 3082 |
gen_op_check_align_T0_3(); |
3204 | 3083 |
gen_movl_reg_T1(rd); |
3205 |
gen_op_ldst(swap); |
|
3084 |
ABI32_MASK(cpu_T[0]); |
|
3085 |
tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx); |
|
3086 |
tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3087 |
tcg_gen_mov_i32(cpu_T[1], cpu_tmp0); |
|
3206 | 3088 |
break; |
3207 | 3089 |
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) |
3208 | 3090 |
case 0x10: /* load word alternate */ |
... | ... | |
3297 | 3179 |
#ifdef TARGET_SPARC64 |
3298 | 3180 |
case 0x08: /* V9 ldsw */ |
3299 | 3181 |
gen_op_check_align_T0_3(); |
3300 |
gen_op_ldst(ldsw); |
|
3182 |
ABI32_MASK(cpu_T[0]); |
|
3183 |
tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3301 | 3184 |
break; |
3302 | 3185 |
case 0x0b: /* V9 ldx */ |
3303 | 3186 |
gen_op_check_align_T0_7(); |
3304 |
gen_op_ldst(ldx); |
|
3187 |
ABI32_MASK(cpu_T[0]); |
|
3188 |
tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3305 | 3189 |
break; |
3306 | 3190 |
case 0x18: /* V9 ldswa */ |
3307 | 3191 |
gen_op_check_align_T0_3(); |
... | ... | |
3374 | 3258 |
xop == 0xe || xop == 0x1e) { |
3375 | 3259 |
gen_movl_reg_T1(rd); |
3376 | 3260 |
switch (xop) { |
3377 |
case 0x4: |
|
3261 |
case 0x4: /* store word */
|
|
3378 | 3262 |
gen_op_check_align_T0_3(); |
3379 |
gen_op_ldst(st); |
|
3263 |
ABI32_MASK(cpu_T[0]); |
|
3264 |
tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3380 | 3265 |
break; |
3381 |
case 0x5: |
|
3382 |
gen_op_ldst(stb); |
|
3266 |
case 0x5: /* store byte */ |
|
3267 |
ABI32_MASK(cpu_T[0]); |
|
3268 |
tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3383 | 3269 |
break; |
3384 |
case 0x6: |
|
3270 |
case 0x6: /* store halfword */
|
|
3385 | 3271 |
gen_op_check_align_T0_1(); |
3386 |
gen_op_ldst(sth); |
|
3272 |
ABI32_MASK(cpu_T[0]); |
|
3273 |
tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx); |
|
3387 | 3274 |
break; |
3388 |
case 0x7: |
|
3275 |
case 0x7: /* store double word */
|
|
3389 | 3276 |
if (rd & 1) |
3390 | 3277 |
goto illegal_insn; |
3391 |
gen_op_check_align_T0_7(); |
|
3392 |
flush_T2(dc); |
|
3393 |
gen_movl_reg_T2(rd + 1); |
|
3394 |
gen_op_ldst(std); |
|
3278 |
else { |
|
3279 |
TCGv r_dword, r_low; |
|
3280 |
|
|
3281 |
gen_op_check_align_T0_7(); |
|
3282 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
3283 |
r_low = tcg_temp_new(TCG_TYPE_I32); |
|
3284 |
gen_movl_reg_TN(rd + 1, r_low); |
|
3285 |
tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1], |
|
3286 |
r_low); |
|
3287 |
tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx); |
|
3288 |
} |
|
3395 | 3289 |
break; |
3396 | 3290 |
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) |
3397 |
case 0x14: |
|
3291 |
case 0x14: /* store word alternate */
|
|
3398 | 3292 |
#ifndef TARGET_SPARC64 |
3399 | 3293 |
if (IS_IMM) |
3400 | 3294 |
goto illegal_insn; |
... | ... | |
3404 | 3298 |
gen_op_check_align_T0_3(); |
3405 | 3299 |
gen_st_asi(insn, 4); |
3406 | 3300 |
break; |
3407 |
case 0x15: |
|
3301 |
case 0x15: /* store byte alternate */
|
|
3408 | 3302 |
#ifndef TARGET_SPARC64 |
3409 | 3303 |
if (IS_IMM) |
3410 | 3304 |
goto illegal_insn; |
... | ... | |
3413 | 3307 |
#endif |
3414 | 3308 |
gen_st_asi(insn, 1); |
3415 | 3309 |
break; |
3416 |
case 0x16: |
|
3310 |
case 0x16: /* store halfword alternate */
|
|
3417 | 3311 |
#ifndef TARGET_SPARC64 |
3418 | 3312 |
if (IS_IMM) |
3419 | 3313 |
goto illegal_insn; |
... | ... | |
3423 | 3317 |
gen_op_check_align_T0_1(); |
3424 | 3318 |
gen_st_asi(insn, 2); |
3425 | 3319 |
break; |
3426 |
case 0x17: |
|
3320 |
case 0x17: /* store double word alternate */
|
|
3427 | 3321 |
#ifndef TARGET_SPARC64 |
3428 | 3322 |
if (IS_IMM) |
3429 | 3323 |
goto illegal_insn; |
... | ... | |
3432 | 3326 |
#endif |
3433 | 3327 |
if (rd & 1) |
3434 | 3328 |
goto illegal_insn; |
3435 |
gen_op_check_align_T0_7(); |
|
3436 |
flush_T2(dc); |
|
3437 |
gen_movl_reg_T2(rd + 1); |
|
3438 |
gen_stda_asi(insn); |
|
3329 |
else { |
|
3330 |
int asi; |
|
3331 |
TCGv r_dword, r_temp, r_size; |
|
3332 |
|
|
3333 |
gen_op_check_align_T0_7(); |
|
3334 |
r_dword = tcg_temp_new(TCG_TYPE_I64); |
|
3335 |
r_temp = tcg_temp_new(TCG_TYPE_I32); |
|
3336 |
r_size = tcg_temp_new(TCG_TYPE_I32); |
|
3337 |
gen_movl_reg_TN(rd + 1, r_temp); |
|
3338 |
tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1], |
|
3339 |
r_temp); |
|
3340 |
#ifdef TARGET_SPARC64 |
|
3341 |
if (IS_IMM) { |
|
3342 |
int offset; |
|
3343 |
|
|
3344 |
offset = GET_FIELD(insn, 25, 31); |
|
3345 |
tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset); |
|
3346 |
tcg_gen_ld_i32(r_dword, cpu_env, offsetof(CPUSPARCState, asi)); |
|
3347 |
} else { |
|
3348 |
#endif |
|
3349 |
asi = GET_FIELD(insn, 19, 26); |
|
3350 |
tcg_gen_movi_i32(r_temp, asi); |
|
3351 |
#ifdef TARGET_SPARC64 |
|
3352 |
} |
|
3353 |
#endif |
|
3354 |
tcg_gen_movi_i32(r_size, 8); |
Also available in: Unified diff