1 /* 2 * CRIS emulation for qemu: main translation routines. 3 * 4 * Copyright (c) 2008 AXIS Communications AB 5 * Written by Edgar E. Iglesias. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 /* 22 * FIXME: 23 * The condition code translation is in need of attention. 24 */ 25 26 #include "qemu/osdep.h" 27 #include "cpu.h" 28 #include "disas/disas.h" 29 #include "exec/exec-all.h" 30 #include "tcg-op.h" 31 #include "exec/helper-proto.h" 32 #include "mmu.h" 33 #include "exec/cpu_ldst.h" 34 #include "crisv32-decode.h" 35 36 #include "exec/helper-gen.h" 37 38 #include "trace-tcg.h" 39 #include "exec/log.h" 40 41 42 #define DISAS_CRIS 0 43 #if DISAS_CRIS 44 # define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) 45 #else 46 # define LOG_DIS(...) do { } while (0) 47 #endif 48 49 #define D(x) 50 #define BUG() (gen_BUG(dc, __FILE__, __LINE__)) 51 #define BUG_ON(x) ({if (x) BUG();}) 52 53 #define DISAS_SWI 5 54 55 /* Used by the decoder. */ 56 #define EXTRACT_FIELD(src, start, end) \ 57 (((src) >> start) & ((1 << (end - start + 1)) - 1)) 58 59 #define CC_MASK_NZ 0xc 60 #define CC_MASK_NZV 0xe 61 #define CC_MASK_NZVC 0xf 62 #define CC_MASK_RNZV 0x10e 63 64 static TCGv_env cpu_env; 65 static TCGv cpu_R[16]; 66 static TCGv cpu_PR[16]; 67 static TCGv cc_x; 68 static TCGv cc_src; 69 static TCGv cc_dest; 70 static TCGv cc_result; 71 static TCGv cc_op; 72 static TCGv cc_size; 73 static TCGv cc_mask; 74 75 static TCGv env_btaken; 76 static TCGv env_btarget; 77 static TCGv env_pc; 78 79 #include "exec/gen-icount.h" 80 81 /* This is the state at translation time. */ 82 typedef struct DisasContext { 83 CRISCPU *cpu; 84 target_ulong pc, ppc; 85 86 /* Decoder. */ 87 unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc); 88 uint32_t ir; 89 uint32_t opcode; 90 unsigned int op1; 91 unsigned int op2; 92 unsigned int zsize, zzsize; 93 unsigned int mode; 94 unsigned int postinc; 95 96 unsigned int size; 97 unsigned int src; 98 unsigned int dst; 99 unsigned int cond; 100 101 int update_cc; 102 int cc_op; 103 int cc_size; 104 uint32_t cc_mask; 105 106 int cc_size_uptodate; /* -1 invalid or last written value. */ 107 108 int cc_x_uptodate; /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date. */ 109 int flags_uptodate; /* Whether or not $ccs is up-to-date. */ 110 int flagx_known; /* Whether or not flags_x has the x flag known at 111 translation time. */ 112 int flags_x; 113 114 int clear_x; /* Clear x after this insn? */ 115 int clear_prefix; /* Clear prefix after this insn? */ 116 int clear_locked_irq; /* Clear the irq lockout. */ 117 int cpustate_changed; 118 unsigned int tb_flags; /* tb dependent flags. */ 119 int is_jmp; 120 121 #define JMP_NOJMP 0 122 #define JMP_DIRECT 1 123 #define JMP_DIRECT_CC 2 124 #define JMP_INDIRECT 3 125 int jmp; /* 0=nojmp, 1=direct, 2=indirect. */ 126 uint32_t jmp_pc; 127 128 int delayed_branch; 129 130 struct TranslationBlock *tb; 131 int singlestep_enabled; 132 } DisasContext; 133 134 static void gen_BUG(DisasContext *dc, const char *file, int line) 135 { 136 fprintf(stderr, "BUG: pc=%x %s %d\n", dc->pc, file, line); 137 if (qemu_log_separate()) { 138 qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line); 139 } 140 cpu_abort(CPU(dc->cpu), "%s:%d\n", file, line); 141 } 142 143 static const char *regnames_v32[] = 144 { 145 "$r0", "$r1", "$r2", "$r3", 146 "$r4", "$r5", "$r6", "$r7", 147 "$r8", "$r9", "$r10", "$r11", 148 "$r12", "$r13", "$sp", "$acr", 149 }; 150 static const char *pregnames_v32[] = 151 { 152 "$bz", "$vr", "$pid", "$srs", 153 "$wz", "$exs", "$eda", "$mof", 154 "$dz", "$ebp", "$erp", "$srp", 155 "$nrp", "$ccs", "$usp", "$spc", 156 }; 157 158 /* We need this table to handle preg-moves with implicit width. */ 159 static int preg_sizes[] = { 160 1, /* bz. */ 161 1, /* vr. */ 162 4, /* pid. */ 163 1, /* srs. */ 164 2, /* wz. */ 165 4, 4, 4, 166 4, 4, 4, 4, 167 4, 4, 4, 4, 168 }; 169 170 #define t_gen_mov_TN_env(tn, member) \ 171 tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUCRISState, member)) 172 #define t_gen_mov_env_TN(member, tn) \ 173 tcg_gen_st_tl(tn, cpu_env, offsetof(CPUCRISState, member)) 174 175 static inline void t_gen_mov_TN_preg(TCGv tn, int r) 176 { 177 assert(r >= 0 && r <= 15); 178 if (r == PR_BZ || r == PR_WZ || r == PR_DZ) { 179 tcg_gen_mov_tl(tn, tcg_const_tl(0)); 180 } else if (r == PR_VR) { 181 tcg_gen_mov_tl(tn, tcg_const_tl(32)); 182 } else { 183 tcg_gen_mov_tl(tn, cpu_PR[r]); 184 } 185 } 186 static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn) 187 { 188 assert(r >= 0 && r <= 15); 189 if (r == PR_BZ || r == PR_WZ || r == PR_DZ) { 190 return; 191 } else if (r == PR_SRS) { 192 tcg_gen_andi_tl(cpu_PR[r], tn, 3); 193 } else { 194 if (r == PR_PID) { 195 gen_helper_tlb_flush_pid(cpu_env, tn); 196 } 197 if (dc->tb_flags & S_FLAG && r == PR_SPC) { 198 gen_helper_spc_write(cpu_env, tn); 199 } else if (r == PR_CCS) { 200 dc->cpustate_changed = 1; 201 } 202 tcg_gen_mov_tl(cpu_PR[r], tn); 203 } 204 } 205 206 /* Sign extend at translation time. */ 207 static int sign_extend(unsigned int val, unsigned int width) 208 { 209 int sval; 210 211 /* LSL. */ 212 val <<= 31 - width; 213 sval = val; 214 /* ASR. */ 215 sval >>= 31 - width; 216 return sval; 217 } 218 219 static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr, 220 unsigned int size, unsigned int sign) 221 { 222 int r; 223 224 switch (size) { 225 case 4: 226 { 227 r = cpu_ldl_code(env, addr); 228 break; 229 } 230 case 2: 231 { 232 if (sign) { 233 r = cpu_ldsw_code(env, addr); 234 } else { 235 r = cpu_lduw_code(env, addr); 236 } 237 break; 238 } 239 case 1: 240 { 241 if (sign) { 242 r = cpu_ldsb_code(env, addr); 243 } else { 244 r = cpu_ldub_code(env, addr); 245 } 246 break; 247 } 248 default: 249 cpu_abort(CPU(dc->cpu), "Invalid fetch size %d\n", size); 250 break; 251 } 252 return r; 253 } 254 255 static void cris_lock_irq(DisasContext *dc) 256 { 257 dc->clear_locked_irq = 0; 258 t_gen_mov_env_TN(locked_irq, tcg_const_tl(1)); 259 } 260 261 static inline void t_gen_raise_exception(uint32_t index) 262 { 263 TCGv_i32 tmp = tcg_const_i32(index); 264 gen_helper_raise_exception(cpu_env, tmp); 265 tcg_temp_free_i32(tmp); 266 } 267 268 static void t_gen_lsl(TCGv d, TCGv a, TCGv b) 269 { 270 TCGv t0, t_31; 271 272 t0 = tcg_temp_new(); 273 t_31 = tcg_const_tl(31); 274 tcg_gen_shl_tl(d, a, b); 275 276 tcg_gen_sub_tl(t0, t_31, b); 277 tcg_gen_sar_tl(t0, t0, t_31); 278 tcg_gen_and_tl(t0, t0, d); 279 tcg_gen_xor_tl(d, d, t0); 280 tcg_temp_free(t0); 281 tcg_temp_free(t_31); 282 } 283 284 static void t_gen_lsr(TCGv d, TCGv a, TCGv b) 285 { 286 TCGv t0, t_31; 287 288 t0 = tcg_temp_new(); 289 t_31 = tcg_temp_new(); 290 tcg_gen_shr_tl(d, a, b); 291 292 tcg_gen_movi_tl(t_31, 31); 293 tcg_gen_sub_tl(t0, t_31, b); 294 tcg_gen_sar_tl(t0, t0, t_31); 295 tcg_gen_and_tl(t0, t0, d); 296 tcg_gen_xor_tl(d, d, t0); 297 tcg_temp_free(t0); 298 tcg_temp_free(t_31); 299 } 300 301 static void t_gen_asr(TCGv d, TCGv a, TCGv b) 302 { 303 TCGv t0, t_31; 304 305 t0 = tcg_temp_new(); 306 t_31 = tcg_temp_new(); 307 tcg_gen_sar_tl(d, a, b); 308 309 tcg_gen_movi_tl(t_31, 31); 310 tcg_gen_sub_tl(t0, t_31, b); 311 tcg_gen_sar_tl(t0, t0, t_31); 312 tcg_gen_or_tl(d, d, t0); 313 tcg_temp_free(t0); 314 tcg_temp_free(t_31); 315 } 316 317 static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b) 318 { 319 TCGv t = tcg_temp_new(); 320 321 /* 322 * d <<= 1 323 * if (d >= s) 324 * d -= s; 325 */ 326 tcg_gen_shli_tl(d, a, 1); 327 tcg_gen_sub_tl(t, d, b); 328 tcg_gen_movcond_tl(TCG_COND_GEU, d, d, b, t, d); 329 tcg_temp_free(t); 330 } 331 332 static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs) 333 { 334 TCGv t; 335 336 /* 337 * d <<= 1 338 * if (n) 339 * d += s; 340 */ 341 t = tcg_temp_new(); 342 tcg_gen_shli_tl(d, a, 1); 343 tcg_gen_shli_tl(t, ccs, 31 - 3); 344 tcg_gen_sari_tl(t, t, 31); 345 tcg_gen_and_tl(t, t, b); 346 tcg_gen_add_tl(d, d, t); 347 tcg_temp_free(t); 348 } 349 350 /* Extended arithmetics on CRIS. */ 351 static inline void t_gen_add_flag(TCGv d, int flag) 352 { 353 TCGv c; 354 355 c = tcg_temp_new(); 356 t_gen_mov_TN_preg(c, PR_CCS); 357 /* Propagate carry into d. */ 358 tcg_gen_andi_tl(c, c, 1 << flag); 359 if (flag) { 360 tcg_gen_shri_tl(c, c, flag); 361 } 362 tcg_gen_add_tl(d, d, c); 363 tcg_temp_free(c); 364 } 365 366 static inline void t_gen_addx_carry(DisasContext *dc, TCGv d) 367 { 368 if (dc->flagx_known) { 369 if (dc->flags_x) { 370 TCGv c; 371 372 c = tcg_temp_new(); 373 t_gen_mov_TN_preg(c, PR_CCS); 374 /* C flag is already at bit 0. */ 375 tcg_gen_andi_tl(c, c, C_FLAG); 376 tcg_gen_add_tl(d, d, c); 377 tcg_temp_free(c); 378 } 379 } else { 380 TCGv x, c; 381 382 x = tcg_temp_new(); 383 c = tcg_temp_new(); 384 t_gen_mov_TN_preg(x, PR_CCS); 385 tcg_gen_mov_tl(c, x); 386 387 /* Propagate carry into d if X is set. Branch free. */ 388 tcg_gen_andi_tl(c, c, C_FLAG); 389 tcg_gen_andi_tl(x, x, X_FLAG); 390 tcg_gen_shri_tl(x, x, 4); 391 392 tcg_gen_and_tl(x, x, c); 393 tcg_gen_add_tl(d, d, x); 394 tcg_temp_free(x); 395 tcg_temp_free(c); 396 } 397 } 398 399 static inline void t_gen_subx_carry(DisasContext *dc, TCGv d) 400 { 401 if (dc->flagx_known) { 402 if (dc->flags_x) { 403 TCGv c; 404 405 c = tcg_temp_new(); 406 t_gen_mov_TN_preg(c, PR_CCS); 407 /* C flag is already at bit 0. */ 408 tcg_gen_andi_tl(c, c, C_FLAG); 409 tcg_gen_sub_tl(d, d, c); 410 tcg_temp_free(c); 411 } 412 } else { 413 TCGv x, c; 414 415 x = tcg_temp_new(); 416 c = tcg_temp_new(); 417 t_gen_mov_TN_preg(x, PR_CCS); 418 tcg_gen_mov_tl(c, x); 419 420 /* Propagate carry into d if X is set. Branch free. */ 421 tcg_gen_andi_tl(c, c, C_FLAG); 422 tcg_gen_andi_tl(x, x, X_FLAG); 423 tcg_gen_shri_tl(x, x, 4); 424 425 tcg_gen_and_tl(x, x, c); 426 tcg_gen_sub_tl(d, d, x); 427 tcg_temp_free(x); 428 tcg_temp_free(c); 429 } 430 } 431 432 /* Swap the two bytes within each half word of the s operand. 433 T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */ 434 static inline void t_gen_swapb(TCGv d, TCGv s) 435 { 436 TCGv t, org_s; 437 438 t = tcg_temp_new(); 439 org_s = tcg_temp_new(); 440 441 /* d and s may refer to the same object. */ 442 tcg_gen_mov_tl(org_s, s); 443 tcg_gen_shli_tl(t, org_s, 8); 444 tcg_gen_andi_tl(d, t, 0xff00ff00); 445 tcg_gen_shri_tl(t, org_s, 8); 446 tcg_gen_andi_tl(t, t, 0x00ff00ff); 447 tcg_gen_or_tl(d, d, t); 448 tcg_temp_free(t); 449 tcg_temp_free(org_s); 450 } 451 452 /* Swap the halfwords of the s operand. */ 453 static inline void t_gen_swapw(TCGv d, TCGv s) 454 { 455 TCGv t; 456 /* d and s refer the same object. */ 457 t = tcg_temp_new(); 458 tcg_gen_mov_tl(t, s); 459 tcg_gen_shli_tl(d, t, 16); 460 tcg_gen_shri_tl(t, t, 16); 461 tcg_gen_or_tl(d, d, t); 462 tcg_temp_free(t); 463 } 464 465 /* Reverse the within each byte. 466 T0 = (((T0 << 7) & 0x80808080) | 467 ((T0 << 5) & 0x40404040) | 468 ((T0 << 3) & 0x20202020) | 469 ((T0 << 1) & 0x10101010) | 470 ((T0 >> 1) & 0x08080808) | 471 ((T0 >> 3) & 0x04040404) | 472 ((T0 >> 5) & 0x02020202) | 473 ((T0 >> 7) & 0x01010101)); 474 */ 475 static inline void t_gen_swapr(TCGv d, TCGv s) 476 { 477 struct { 478 int shift; /* LSL when positive, LSR when negative. */ 479 uint32_t mask; 480 } bitrev[] = { 481 {7, 0x80808080}, 482 {5, 0x40404040}, 483 {3, 0x20202020}, 484 {1, 0x10101010}, 485 {-1, 0x08080808}, 486 {-3, 0x04040404}, 487 {-5, 0x02020202}, 488 {-7, 0x01010101} 489 }; 490 int i; 491 TCGv t, org_s; 492 493 /* d and s refer the same object. */ 494 t = tcg_temp_new(); 495 org_s = tcg_temp_new(); 496 tcg_gen_mov_tl(org_s, s); 497 498 tcg_gen_shli_tl(t, org_s, bitrev[0].shift); 499 tcg_gen_andi_tl(d, t, bitrev[0].mask); 500 for (i = 1; i < ARRAY_SIZE(bitrev); i++) { 501 if (bitrev[i].shift >= 0) { 502 tcg_gen_shli_tl(t, org_s, bitrev[i].shift); 503 } else { 504 tcg_gen_shri_tl(t, org_s, -bitrev[i].shift); 505 } 506 tcg_gen_andi_tl(t, t, bitrev[i].mask); 507 tcg_gen_or_tl(d, d, t); 508 } 509 tcg_temp_free(t); 510 tcg_temp_free(org_s); 511 } 512 513 static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false) 514 { 515 TCGLabel *l1 = gen_new_label(); 516 517 /* Conditional jmp. */ 518 tcg_gen_mov_tl(env_pc, pc_false); 519 tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1); 520 tcg_gen_mov_tl(env_pc, pc_true); 521 gen_set_label(l1); 522 } 523 524 static inline bool use_goto_tb(DisasContext *dc, target_ulong dest) 525 { 526 #ifndef CONFIG_USER_ONLY 527 return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) || 528 (dc->ppc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 529 #else 530 return true; 531 #endif 532 } 533 534 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) 535 { 536 if (use_goto_tb(dc, dest)) { 537 tcg_gen_goto_tb(n); 538 tcg_gen_movi_tl(env_pc, dest); 539 tcg_gen_exit_tb((uintptr_t)dc->tb + n); 540 } else { 541 tcg_gen_movi_tl(env_pc, dest); 542 tcg_gen_exit_tb(0); 543 } 544 } 545 546 static inline void cris_clear_x_flag(DisasContext *dc) 547 { 548 if (dc->flagx_known && dc->flags_x) { 549 dc->flags_uptodate = 0; 550 } 551 552 dc->flagx_known = 1; 553 dc->flags_x = 0; 554 } 555 556 static void cris_flush_cc_state(DisasContext *dc) 557 { 558 if (dc->cc_size_uptodate != dc->cc_size) { 559 tcg_gen_movi_tl(cc_size, dc->cc_size); 560 dc->cc_size_uptodate = dc->cc_size; 561 } 562 tcg_gen_movi_tl(cc_op, dc->cc_op); 563 tcg_gen_movi_tl(cc_mask, dc->cc_mask); 564 } 565 566 static void cris_evaluate_flags(DisasContext *dc) 567 { 568 if (dc->flags_uptodate) { 569 return; 570 } 571 572 cris_flush_cc_state(dc); 573 574 switch (dc->cc_op) { 575 case CC_OP_MCP: 576 gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env, 577 cpu_PR[PR_CCS], cc_src, 578 cc_dest, cc_result); 579 break; 580 case CC_OP_MULS: 581 gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env, 582 cpu_PR[PR_CCS], cc_result, 583 cpu_PR[PR_MOF]); 584 break; 585 case CC_OP_MULU: 586 gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env, 587 cpu_PR[PR_CCS], cc_result, 588 cpu_PR[PR_MOF]); 589 break; 590 case CC_OP_MOVE: 591 case CC_OP_AND: 592 case CC_OP_OR: 593 case CC_OP_XOR: 594 case CC_OP_ASR: 595 case CC_OP_LSR: 596 case CC_OP_LSL: 597 switch (dc->cc_size) { 598 case 4: 599 gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS], 600 cpu_env, cpu_PR[PR_CCS], cc_result); 601 break; 602 case 2: 603 gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS], 604 cpu_env, cpu_PR[PR_CCS], cc_result); 605 break; 606 default: 607 gen_helper_evaluate_flags(cpu_env); 608 break; 609 } 610 break; 611 case CC_OP_FLAGS: 612 /* live. */ 613 break; 614 case CC_OP_SUB: 615 case CC_OP_CMP: 616 if (dc->cc_size == 4) { 617 gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env, 618 cpu_PR[PR_CCS], cc_src, cc_dest, cc_result); 619 } else { 620 gen_helper_evaluate_flags(cpu_env); 621 } 622 623 break; 624 default: 625 switch (dc->cc_size) { 626 case 4: 627 gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env, 628 cpu_PR[PR_CCS], cc_src, cc_dest, cc_result); 629 break; 630 default: 631 gen_helper_evaluate_flags(cpu_env); 632 break; 633 } 634 break; 635 } 636 637 if (dc->flagx_known) { 638 if (dc->flags_x) { 639 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG); 640 } else if (dc->cc_op == CC_OP_FLAGS) { 641 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG); 642 } 643 } 644 dc->flags_uptodate = 1; 645 } 646 647 static void cris_cc_mask(DisasContext *dc, unsigned int mask) 648 { 649 uint32_t ovl; 650 651 if (!mask) { 652 dc->update_cc = 0; 653 return; 654 } 655 656 /* Check if we need to evaluate the condition codes due to 657 CC overlaying. */ 658 ovl = (dc->cc_mask ^ mask) & ~mask; 659 if (ovl) { 660 /* TODO: optimize this case. It trigs all the time. */ 661 cris_evaluate_flags(dc); 662 } 663 dc->cc_mask = mask; 664 dc->update_cc = 1; 665 } 666 667 static void cris_update_cc_op(DisasContext *dc, int op, int size) 668 { 669 dc->cc_op = op; 670 dc->cc_size = size; 671 dc->flags_uptodate = 0; 672 } 673 674 static inline void cris_update_cc_x(DisasContext *dc) 675 { 676 /* Save the x flag state at the time of the cc snapshot. */ 677 if (dc->flagx_known) { 678 if (dc->cc_x_uptodate == (2 | dc->flags_x)) { 679 return; 680 } 681 tcg_gen_movi_tl(cc_x, dc->flags_x); 682 dc->cc_x_uptodate = 2 | dc->flags_x; 683 } else { 684 tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG); 685 dc->cc_x_uptodate = 1; 686 } 687 } 688 689 /* Update cc prior to executing ALU op. Needs source operands untouched. */ 690 static void cris_pre_alu_update_cc(DisasContext *dc, int op, 691 TCGv dst, TCGv src, int size) 692 { 693 if (dc->update_cc) { 694 cris_update_cc_op(dc, op, size); 695 tcg_gen_mov_tl(cc_src, src); 696 697 if (op != CC_OP_MOVE 698 && op != CC_OP_AND 699 && op != CC_OP_OR 700 && op != CC_OP_XOR 701 && op != CC_OP_ASR 702 && op != CC_OP_LSR 703 && op != CC_OP_LSL) { 704 tcg_gen_mov_tl(cc_dest, dst); 705 } 706 707 cris_update_cc_x(dc); 708 } 709 } 710 711 /* Update cc after executing ALU op. needs the result. */ 712 static inline void cris_update_result(DisasContext *dc, TCGv res) 713 { 714 if (dc->update_cc) { 715 tcg_gen_mov_tl(cc_result, res); 716 } 717 } 718 719 /* Returns one if the write back stage should execute. */ 720 static void cris_alu_op_exec(DisasContext *dc, int op, 721 TCGv dst, TCGv a, TCGv b, int size) 722 { 723 /* Emit the ALU insns. */ 724 switch (op) { 725 case CC_OP_ADD: 726 tcg_gen_add_tl(dst, a, b); 727 /* Extended arithmetics. */ 728 t_gen_addx_carry(dc, dst); 729 break; 730 case CC_OP_ADDC: 731 tcg_gen_add_tl(dst, a, b); 732 t_gen_add_flag(dst, 0); /* C_FLAG. */ 733 break; 734 case CC_OP_MCP: 735 tcg_gen_add_tl(dst, a, b); 736 t_gen_add_flag(dst, 8); /* R_FLAG. */ 737 break; 738 case CC_OP_SUB: 739 tcg_gen_sub_tl(dst, a, b); 740 /* Extended arithmetics. */ 741 t_gen_subx_carry(dc, dst); 742 break; 743 case CC_OP_MOVE: 744 tcg_gen_mov_tl(dst, b); 745 break; 746 case CC_OP_OR: 747 tcg_gen_or_tl(dst, a, b); 748 break; 749 case CC_OP_AND: 750 tcg_gen_and_tl(dst, a, b); 751 break; 752 case CC_OP_XOR: 753 tcg_gen_xor_tl(dst, a, b); 754 break; 755 case CC_OP_LSL: 756 t_gen_lsl(dst, a, b); 757 break; 758 case CC_OP_LSR: 759 t_gen_lsr(dst, a, b); 760 break; 761 case CC_OP_ASR: 762 t_gen_asr(dst, a, b); 763 break; 764 case CC_OP_NEG: 765 tcg_gen_neg_tl(dst, b); 766 /* Extended arithmetics. */ 767 t_gen_subx_carry(dc, dst); 768 break; 769 case CC_OP_LZ: 770 tcg_gen_clzi_tl(dst, b, TARGET_LONG_BITS); 771 break; 772 case CC_OP_MULS: 773 tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b); 774 break; 775 case CC_OP_MULU: 776 tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b); 777 break; 778 case CC_OP_DSTEP: 779 t_gen_cris_dstep(dst, a, b); 780 break; 781 case CC_OP_MSTEP: 782 t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]); 783 break; 784 case CC_OP_BOUND: 785 tcg_gen_movcond_tl(TCG_COND_LEU, dst, a, b, a, b); 786 break; 787 case CC_OP_CMP: 788 tcg_gen_sub_tl(dst, a, b); 789 /* Extended arithmetics. */ 790 t_gen_subx_carry(dc, dst); 791 break; 792 default: 793 qemu_log_mask(LOG_GUEST_ERROR, "illegal ALU op.\n"); 794 BUG(); 795 break; 796 } 797 798 if (size == 1) { 799 tcg_gen_andi_tl(dst, dst, 0xff); 800 } else if (size == 2) { 801 tcg_gen_andi_tl(dst, dst, 0xffff); 802 } 803 } 804 805 static void cris_alu(DisasContext *dc, int op, 806 TCGv d, TCGv op_a, TCGv op_b, int size) 807 { 808 TCGv tmp; 809 int writeback; 810 811 writeback = 1; 812 813 if (op == CC_OP_CMP) { 814 tmp = tcg_temp_new(); 815 writeback = 0; 816 } else if (size == 4) { 817 tmp = d; 818 writeback = 0; 819 } else { 820 tmp = tcg_temp_new(); 821 } 822 823 824 cris_pre_alu_update_cc(dc, op, op_a, op_b, size); 825 cris_alu_op_exec(dc, op, tmp, op_a, op_b, size); 826 cris_update_result(dc, tmp); 827 828 /* Writeback. */ 829 if (writeback) { 830 if (size == 1) { 831 tcg_gen_andi_tl(d, d, ~0xff); 832 } else { 833 tcg_gen_andi_tl(d, d, ~0xffff); 834 } 835 tcg_gen_or_tl(d, d, tmp); 836 } 837 if (!TCGV_EQUAL(tmp, d)) { 838 tcg_temp_free(tmp); 839 } 840 } 841 842 static int arith_cc(DisasContext *dc) 843 { 844 if (dc->update_cc) { 845 switch (dc->cc_op) { 846 case CC_OP_ADDC: return 1; 847 case CC_OP_ADD: return 1; 848 case CC_OP_SUB: return 1; 849 case CC_OP_DSTEP: return 1; 850 case CC_OP_LSL: return 1; 851 case CC_OP_LSR: return 1; 852 case CC_OP_ASR: return 1; 853 case CC_OP_CMP: return 1; 854 case CC_OP_NEG: return 1; 855 case CC_OP_OR: return 1; 856 case CC_OP_AND: return 1; 857 case CC_OP_XOR: return 1; 858 case CC_OP_MULU: return 1; 859 case CC_OP_MULS: return 1; 860 default: 861 return 0; 862 } 863 } 864 return 0; 865 } 866 867 static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond) 868 { 869 int arith_opt, move_opt; 870 871 /* TODO: optimize more condition codes. */ 872 873 /* 874 * If the flags are live, we've gotta look into the bits of CCS. 875 * Otherwise, if we just did an arithmetic operation we try to 876 * evaluate the condition code faster. 877 * 878 * When this function is done, T0 should be non-zero if the condition 879 * code is true. 880 */ 881 arith_opt = arith_cc(dc) && !dc->flags_uptodate; 882 move_opt = (dc->cc_op == CC_OP_MOVE); 883 switch (cond) { 884 case CC_EQ: 885 if ((arith_opt || move_opt) 886 && dc->cc_x_uptodate != (2 | X_FLAG)) { 887 tcg_gen_setcond_tl(TCG_COND_EQ, cc, 888 cc_result, tcg_const_tl(0)); 889 } else { 890 cris_evaluate_flags(dc); 891 tcg_gen_andi_tl(cc, 892 cpu_PR[PR_CCS], Z_FLAG); 893 } 894 break; 895 case CC_NE: 896 if ((arith_opt || move_opt) 897 && dc->cc_x_uptodate != (2 | X_FLAG)) { 898 tcg_gen_mov_tl(cc, cc_result); 899 } else { 900 cris_evaluate_flags(dc); 901 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], 902 Z_FLAG); 903 tcg_gen_andi_tl(cc, cc, Z_FLAG); 904 } 905 break; 906 case CC_CS: 907 cris_evaluate_flags(dc); 908 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG); 909 break; 910 case CC_CC: 911 cris_evaluate_flags(dc); 912 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG); 913 tcg_gen_andi_tl(cc, cc, C_FLAG); 914 break; 915 case CC_VS: 916 cris_evaluate_flags(dc); 917 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG); 918 break; 919 case CC_VC: 920 cris_evaluate_flags(dc); 921 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], 922 V_FLAG); 923 tcg_gen_andi_tl(cc, cc, V_FLAG); 924 break; 925 case CC_PL: 926 if (arith_opt || move_opt) { 927 int bits = 31; 928 929 if (dc->cc_size == 1) { 930 bits = 7; 931 } else if (dc->cc_size == 2) { 932 bits = 15; 933 } 934 935 tcg_gen_shri_tl(cc, cc_result, bits); 936 tcg_gen_xori_tl(cc, cc, 1); 937 } else { 938 cris_evaluate_flags(dc); 939 tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], 940 N_FLAG); 941 tcg_gen_andi_tl(cc, cc, N_FLAG); 942 } 943 break; 944 case CC_MI: 945 if (arith_opt || move_opt) { 946 int bits = 31; 947 948 if (dc->cc_size == 1) { 949 bits = 7; 950 } else if (dc->cc_size == 2) { 951 bits = 15; 952 } 953 954 tcg_gen_shri_tl(cc, cc_result, bits); 955 tcg_gen_andi_tl(cc, cc, 1); 956 } else { 957 cris_evaluate_flags(dc); 958 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], 959 N_FLAG); 960 } 961 break; 962 case CC_LS: 963 cris_evaluate_flags(dc); 964 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], 965 C_FLAG | Z_FLAG); 966 break; 967 case CC_HI: 968 cris_evaluate_flags(dc); 969 { 970 TCGv tmp; 971 972 tmp = tcg_temp_new(); 973 tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS], 974 C_FLAG | Z_FLAG); 975 /* Overlay the C flag on top of the Z. */ 976 tcg_gen_shli_tl(cc, tmp, 2); 977 tcg_gen_and_tl(cc, tmp, cc); 978 tcg_gen_andi_tl(cc, cc, Z_FLAG); 979 980 tcg_temp_free(tmp); 981 } 982 break; 983 case CC_GE: 984 cris_evaluate_flags(dc); 985 /* Overlay the V flag on top of the N. */ 986 tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2); 987 tcg_gen_xor_tl(cc, 988 cpu_PR[PR_CCS], cc); 989 tcg_gen_andi_tl(cc, cc, N_FLAG); 990 tcg_gen_xori_tl(cc, cc, N_FLAG); 991 break; 992 case CC_LT: 993 cris_evaluate_flags(dc); 994 /* Overlay the V flag on top of the N. */ 995 tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2); 996 tcg_gen_xor_tl(cc, 997 cpu_PR[PR_CCS], cc); 998 tcg_gen_andi_tl(cc, cc, N_FLAG); 999 break; 1000 case CC_GT: 1001 cris_evaluate_flags(dc); 1002 { 1003 TCGv n, z; 1004 1005 n = tcg_temp_new(); 1006 z = tcg_temp_new(); 1007 1008 /* To avoid a shift we overlay everything on 1009 the V flag. */ 1010 tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2); 1011 tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1); 1012 /* invert Z. */ 1013 tcg_gen_xori_tl(z, z, 2); 1014 1015 tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]); 1016 tcg_gen_xori_tl(n, n, 2); 1017 tcg_gen_and_tl(cc, z, n); 1018 tcg_gen_andi_tl(cc, cc, 2); 1019 1020 tcg_temp_free(n); 1021 tcg_temp_free(z); 1022 } 1023 break; 1024 case CC_LE: 1025 cris_evaluate_flags(dc); 1026 { 1027 TCGv n, z; 1028 1029 n = tcg_temp_new(); 1030 z = tcg_temp_new(); 1031 1032 /* To avoid a shift we overlay everything on 1033 the V flag. */ 1034 tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2); 1035 tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1); 1036 1037 tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]); 1038 tcg_gen_or_tl(cc, z, n); 1039 tcg_gen_andi_tl(cc, cc, 2); 1040 1041 tcg_temp_free(n); 1042 tcg_temp_free(z); 1043 } 1044 break; 1045 case CC_P: 1046 cris_evaluate_flags(dc); 1047 tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG); 1048 break; 1049 case CC_A: 1050 tcg_gen_movi_tl(cc, 1); 1051 break; 1052 default: 1053 BUG(); 1054 break; 1055 }; 1056 } 1057 1058 static void cris_store_direct_jmp(DisasContext *dc) 1059 { 1060 /* Store the direct jmp state into the cpu-state. */ 1061 if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) { 1062 if (dc->jmp == JMP_DIRECT) { 1063 tcg_gen_movi_tl(env_btaken, 1); 1064 } 1065 tcg_gen_movi_tl(env_btarget, dc->jmp_pc); 1066 dc->jmp = JMP_INDIRECT; 1067 } 1068 } 1069 1070 static void cris_prepare_cc_branch (DisasContext *dc, 1071 int offset, int cond) 1072 { 1073 /* This helps us re-schedule the micro-code to insns in delay-slots 1074 before the actual jump. */ 1075 dc->delayed_branch = 2; 1076 dc->jmp = JMP_DIRECT_CC; 1077 dc->jmp_pc = dc->pc + offset; 1078 1079 gen_tst_cc(dc, env_btaken, cond); 1080 tcg_gen_movi_tl(env_btarget, dc->jmp_pc); 1081 } 1082 1083 1084 /* jumps, when the dest is in a live reg for example. Direct should be set 1085 when the dest addr is constant to allow tb chaining. */ 1086 static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type) 1087 { 1088 /* This helps us re-schedule the micro-code to insns in delay-slots 1089 before the actual jump. */ 1090 dc->delayed_branch = 2; 1091 dc->jmp = type; 1092 if (type == JMP_INDIRECT) { 1093 tcg_gen_movi_tl(env_btaken, 1); 1094 } 1095 } 1096 1097 static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr) 1098 { 1099 int mem_index = cpu_mmu_index(&dc->cpu->env, false); 1100 1101 /* If we get a fault on a delayslot we must keep the jmp state in 1102 the cpu-state to be able to re-execute the jmp. */ 1103 if (dc->delayed_branch == 1) { 1104 cris_store_direct_jmp(dc); 1105 } 1106 1107 tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEQ); 1108 } 1109 1110 static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, 1111 unsigned int size, int sign) 1112 { 1113 int mem_index = cpu_mmu_index(&dc->cpu->env, false); 1114 1115 /* If we get a fault on a delayslot we must keep the jmp state in 1116 the cpu-state to be able to re-execute the jmp. */ 1117 if (dc->delayed_branch == 1) { 1118 cris_store_direct_jmp(dc); 1119 } 1120 1121 tcg_gen_qemu_ld_tl(dst, addr, mem_index, 1122 MO_TE + ctz32(size) + (sign ? MO_SIGN : 0)); 1123 } 1124 1125 static void gen_store (DisasContext *dc, TCGv addr, TCGv val, 1126 unsigned int size) 1127 { 1128 int mem_index = cpu_mmu_index(&dc->cpu->env, false); 1129 1130 /* If we get a fault on a delayslot we must keep the jmp state in 1131 the cpu-state to be able to re-execute the jmp. */ 1132 if (dc->delayed_branch == 1) { 1133 cris_store_direct_jmp(dc); 1134 } 1135 1136 1137 /* Conditional writes. We only support the kind were X and P are known 1138 at translation time. */ 1139 if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) { 1140 dc->postinc = 0; 1141 cris_evaluate_flags(dc); 1142 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG); 1143 return; 1144 } 1145 1146 tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size)); 1147 1148 if (dc->flagx_known && dc->flags_x) { 1149 cris_evaluate_flags(dc); 1150 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG); 1151 } 1152 } 1153 1154 static inline void t_gen_sext(TCGv d, TCGv s, int size) 1155 { 1156 if (size == 1) { 1157 tcg_gen_ext8s_i32(d, s); 1158 } else if (size == 2) { 1159 tcg_gen_ext16s_i32(d, s); 1160 } else if (!TCGV_EQUAL(d, s)) { 1161 tcg_gen_mov_tl(d, s); 1162 } 1163 } 1164 1165 static inline void t_gen_zext(TCGv d, TCGv s, int size) 1166 { 1167 if (size == 1) { 1168 tcg_gen_ext8u_i32(d, s); 1169 } else if (size == 2) { 1170 tcg_gen_ext16u_i32(d, s); 1171 } else if (!TCGV_EQUAL(d, s)) { 1172 tcg_gen_mov_tl(d, s); 1173 } 1174 } 1175 1176 #if DISAS_CRIS 1177 static char memsize_char(int size) 1178 { 1179 switch (size) { 1180 case 1: return 'b'; break; 1181 case 2: return 'w'; break; 1182 case 4: return 'd'; break; 1183 default: 1184 return 'x'; 1185 break; 1186 } 1187 } 1188 #endif 1189 1190 static inline unsigned int memsize_z(DisasContext *dc) 1191 { 1192 return dc->zsize + 1; 1193 } 1194 1195 static inline unsigned int memsize_zz(DisasContext *dc) 1196 { 1197 switch (dc->zzsize) { 1198 case 0: return 1; 1199 case 1: return 2; 1200 default: 1201 return 4; 1202 } 1203 } 1204 1205 static inline void do_postinc (DisasContext *dc, int size) 1206 { 1207 if (dc->postinc) { 1208 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size); 1209 } 1210 } 1211 1212 static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd, 1213 int size, int s_ext, TCGv dst) 1214 { 1215 if (s_ext) { 1216 t_gen_sext(dst, cpu_R[rs], size); 1217 } else { 1218 t_gen_zext(dst, cpu_R[rs], size); 1219 } 1220 } 1221 1222 /* Prepare T0 and T1 for a register alu operation. 1223 s_ext decides if the operand1 should be sign-extended or zero-extended when 1224 needed. */ 1225 static void dec_prep_alu_r(DisasContext *dc, int rs, int rd, 1226 int size, int s_ext, TCGv dst, TCGv src) 1227 { 1228 dec_prep_move_r(dc, rs, rd, size, s_ext, src); 1229 1230 if (s_ext) { 1231 t_gen_sext(dst, cpu_R[rd], size); 1232 } else { 1233 t_gen_zext(dst, cpu_R[rd], size); 1234 } 1235 } 1236 1237 static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc, 1238 int s_ext, int memsize, TCGv dst) 1239 { 1240 unsigned int rs; 1241 uint32_t imm; 1242 int is_imm; 1243 int insn_len = 2; 1244 1245 rs = dc->op1; 1246 is_imm = rs == 15 && dc->postinc; 1247 1248 /* Load [$rs] onto T1. */ 1249 if (is_imm) { 1250 insn_len = 2 + memsize; 1251 if (memsize == 1) { 1252 insn_len++; 1253 } 1254 1255 imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext); 1256 tcg_gen_movi_tl(dst, imm); 1257 dc->postinc = 0; 1258 } else { 1259 cris_flush_cc_state(dc); 1260 gen_load(dc, dst, cpu_R[rs], memsize, 0); 1261 if (s_ext) { 1262 t_gen_sext(dst, dst, memsize); 1263 } else { 1264 t_gen_zext(dst, dst, memsize); 1265 } 1266 } 1267 return insn_len; 1268 } 1269 1270 /* Prepare T0 and T1 for a memory + alu operation. 1271 s_ext decides if the operand1 should be sign-extended or zero-extended when 1272 needed. */ 1273 static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc, 1274 int s_ext, int memsize, TCGv dst, TCGv src) 1275 { 1276 int insn_len; 1277 1278 insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src); 1279 tcg_gen_mov_tl(dst, cpu_R[dc->op2]); 1280 return insn_len; 1281 } 1282 1283 #if DISAS_CRIS 1284 static const char *cc_name(int cc) 1285 { 1286 static const char *cc_names[16] = { 1287 "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", 1288 "ls", "hi", "ge", "lt", "gt", "le", "a", "p" 1289 }; 1290 assert(cc < 16); 1291 return cc_names[cc]; 1292 } 1293 #endif 1294 1295 /* Start of insn decoders. */ 1296 1297 static int dec_bccq(CPUCRISState *env, DisasContext *dc) 1298 { 1299 int32_t offset; 1300 int sign; 1301 uint32_t cond = dc->op2; 1302 1303 offset = EXTRACT_FIELD(dc->ir, 1, 7); 1304 sign = EXTRACT_FIELD(dc->ir, 0, 0); 1305 1306 offset *= 2; 1307 offset |= sign << 8; 1308 offset = sign_extend(offset, 8); 1309 1310 LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset); 1311 1312 /* op2 holds the condition-code. */ 1313 cris_cc_mask(dc, 0); 1314 cris_prepare_cc_branch(dc, offset, cond); 1315 return 2; 1316 } 1317 static int dec_addoq(CPUCRISState *env, DisasContext *dc) 1318 { 1319 int32_t imm; 1320 1321 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7); 1322 imm = sign_extend(dc->op1, 7); 1323 1324 LOG_DIS("addoq %d, $r%u\n", imm, dc->op2); 1325 cris_cc_mask(dc, 0); 1326 /* Fetch register operand, */ 1327 tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm); 1328 1329 return 2; 1330 } 1331 static int dec_addq(CPUCRISState *env, DisasContext *dc) 1332 { 1333 LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2); 1334 1335 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); 1336 1337 cris_cc_mask(dc, CC_MASK_NZVC); 1338 1339 cris_alu(dc, CC_OP_ADD, 1340 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); 1341 return 2; 1342 } 1343 static int dec_moveq(CPUCRISState *env, DisasContext *dc) 1344 { 1345 uint32_t imm; 1346 1347 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); 1348 imm = sign_extend(dc->op1, 5); 1349 LOG_DIS("moveq %d, $r%u\n", imm, dc->op2); 1350 1351 tcg_gen_movi_tl(cpu_R[dc->op2], imm); 1352 return 2; 1353 } 1354 static int dec_subq(CPUCRISState *env, DisasContext *dc) 1355 { 1356 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); 1357 1358 LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2); 1359 1360 cris_cc_mask(dc, CC_MASK_NZVC); 1361 cris_alu(dc, CC_OP_SUB, 1362 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); 1363 return 2; 1364 } 1365 static int dec_cmpq(CPUCRISState *env, DisasContext *dc) 1366 { 1367 uint32_t imm; 1368 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); 1369 imm = sign_extend(dc->op1, 5); 1370 1371 LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2); 1372 cris_cc_mask(dc, CC_MASK_NZVC); 1373 1374 cris_alu(dc, CC_OP_CMP, 1375 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4); 1376 return 2; 1377 } 1378 static int dec_andq(CPUCRISState *env, DisasContext *dc) 1379 { 1380 uint32_t imm; 1381 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); 1382 imm = sign_extend(dc->op1, 5); 1383 1384 LOG_DIS("andq %d, $r%d\n", imm, dc->op2); 1385 cris_cc_mask(dc, CC_MASK_NZ); 1386 1387 cris_alu(dc, CC_OP_AND, 1388 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4); 1389 return 2; 1390 } 1391 static int dec_orq(CPUCRISState *env, DisasContext *dc) 1392 { 1393 uint32_t imm; 1394 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5); 1395 imm = sign_extend(dc->op1, 5); 1396 LOG_DIS("orq %d, $r%d\n", imm, dc->op2); 1397 cris_cc_mask(dc, CC_MASK_NZ); 1398 1399 cris_alu(dc, CC_OP_OR, 1400 cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4); 1401 return 2; 1402 } 1403 static int dec_btstq(CPUCRISState *env, DisasContext *dc) 1404 { 1405 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); 1406 LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2); 1407 1408 cris_cc_mask(dc, CC_MASK_NZ); 1409 cris_evaluate_flags(dc); 1410 gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2], 1411 tcg_const_tl(dc->op1), cpu_PR[PR_CCS]); 1412 cris_alu(dc, CC_OP_MOVE, 1413 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4); 1414 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 1415 dc->flags_uptodate = 1; 1416 return 2; 1417 } 1418 static int dec_asrq(CPUCRISState *env, DisasContext *dc) 1419 { 1420 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); 1421 LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2); 1422 cris_cc_mask(dc, CC_MASK_NZ); 1423 1424 tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1); 1425 cris_alu(dc, CC_OP_MOVE, 1426 cpu_R[dc->op2], 1427 cpu_R[dc->op2], cpu_R[dc->op2], 4); 1428 return 2; 1429 } 1430 static int dec_lslq(CPUCRISState *env, DisasContext *dc) 1431 { 1432 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); 1433 LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2); 1434 1435 cris_cc_mask(dc, CC_MASK_NZ); 1436 1437 tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1); 1438 1439 cris_alu(dc, CC_OP_MOVE, 1440 cpu_R[dc->op2], 1441 cpu_R[dc->op2], cpu_R[dc->op2], 4); 1442 return 2; 1443 } 1444 static int dec_lsrq(CPUCRISState *env, DisasContext *dc) 1445 { 1446 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); 1447 LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2); 1448 1449 cris_cc_mask(dc, CC_MASK_NZ); 1450 1451 tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1); 1452 cris_alu(dc, CC_OP_MOVE, 1453 cpu_R[dc->op2], 1454 cpu_R[dc->op2], cpu_R[dc->op2], 4); 1455 return 2; 1456 } 1457 1458 static int dec_move_r(CPUCRISState *env, DisasContext *dc) 1459 { 1460 int size = memsize_zz(dc); 1461 1462 LOG_DIS("move.%c $r%u, $r%u\n", 1463 memsize_char(size), dc->op1, dc->op2); 1464 1465 cris_cc_mask(dc, CC_MASK_NZ); 1466 if (size == 4) { 1467 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]); 1468 cris_cc_mask(dc, CC_MASK_NZ); 1469 cris_update_cc_op(dc, CC_OP_MOVE, 4); 1470 cris_update_cc_x(dc); 1471 cris_update_result(dc, cpu_R[dc->op2]); 1472 } else { 1473 TCGv t0; 1474 1475 t0 = tcg_temp_new(); 1476 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0); 1477 cris_alu(dc, CC_OP_MOVE, 1478 cpu_R[dc->op2], 1479 cpu_R[dc->op2], t0, size); 1480 tcg_temp_free(t0); 1481 } 1482 return 2; 1483 } 1484 1485 static int dec_scc_r(CPUCRISState *env, DisasContext *dc) 1486 { 1487 int cond = dc->op2; 1488 1489 LOG_DIS("s%s $r%u\n", 1490 cc_name(cond), dc->op1); 1491 1492 gen_tst_cc(dc, cpu_R[dc->op1], cond); 1493 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->op1], cpu_R[dc->op1], 0); 1494 1495 cris_cc_mask(dc, 0); 1496 return 2; 1497 } 1498 1499 static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t) 1500 { 1501 if (size == 4) { 1502 t[0] = cpu_R[dc->op2]; 1503 t[1] = cpu_R[dc->op1]; 1504 } else { 1505 t[0] = tcg_temp_new(); 1506 t[1] = tcg_temp_new(); 1507 } 1508 } 1509 1510 static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t) 1511 { 1512 if (size != 4) { 1513 tcg_temp_free(t[0]); 1514 tcg_temp_free(t[1]); 1515 } 1516 } 1517 1518 static int dec_and_r(CPUCRISState *env, DisasContext *dc) 1519 { 1520 TCGv t[2]; 1521 int size = memsize_zz(dc); 1522 1523 LOG_DIS("and.%c $r%u, $r%u\n", 1524 memsize_char(size), dc->op1, dc->op2); 1525 1526 cris_cc_mask(dc, CC_MASK_NZ); 1527 1528 cris_alu_alloc_temps(dc, size, t); 1529 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1530 cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size); 1531 cris_alu_free_temps(dc, size, t); 1532 return 2; 1533 } 1534 1535 static int dec_lz_r(CPUCRISState *env, DisasContext *dc) 1536 { 1537 TCGv t0; 1538 LOG_DIS("lz $r%u, $r%u\n", 1539 dc->op1, dc->op2); 1540 cris_cc_mask(dc, CC_MASK_NZ); 1541 t0 = tcg_temp_new(); 1542 dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0); 1543 cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4); 1544 tcg_temp_free(t0); 1545 return 2; 1546 } 1547 1548 static int dec_lsl_r(CPUCRISState *env, DisasContext *dc) 1549 { 1550 TCGv t[2]; 1551 int size = memsize_zz(dc); 1552 1553 LOG_DIS("lsl.%c $r%u, $r%u\n", 1554 memsize_char(size), dc->op1, dc->op2); 1555 1556 cris_cc_mask(dc, CC_MASK_NZ); 1557 cris_alu_alloc_temps(dc, size, t); 1558 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1559 tcg_gen_andi_tl(t[1], t[1], 63); 1560 cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size); 1561 cris_alu_alloc_temps(dc, size, t); 1562 return 2; 1563 } 1564 1565 static int dec_lsr_r(CPUCRISState *env, DisasContext *dc) 1566 { 1567 TCGv t[2]; 1568 int size = memsize_zz(dc); 1569 1570 LOG_DIS("lsr.%c $r%u, $r%u\n", 1571 memsize_char(size), dc->op1, dc->op2); 1572 1573 cris_cc_mask(dc, CC_MASK_NZ); 1574 cris_alu_alloc_temps(dc, size, t); 1575 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1576 tcg_gen_andi_tl(t[1], t[1], 63); 1577 cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size); 1578 cris_alu_free_temps(dc, size, t); 1579 return 2; 1580 } 1581 1582 static int dec_asr_r(CPUCRISState *env, DisasContext *dc) 1583 { 1584 TCGv t[2]; 1585 int size = memsize_zz(dc); 1586 1587 LOG_DIS("asr.%c $r%u, $r%u\n", 1588 memsize_char(size), dc->op1, dc->op2); 1589 1590 cris_cc_mask(dc, CC_MASK_NZ); 1591 cris_alu_alloc_temps(dc, size, t); 1592 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]); 1593 tcg_gen_andi_tl(t[1], t[1], 63); 1594 cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size); 1595 cris_alu_free_temps(dc, size, t); 1596 return 2; 1597 } 1598 1599 static int dec_muls_r(CPUCRISState *env, DisasContext *dc) 1600 { 1601 TCGv t[2]; 1602 int size = memsize_zz(dc); 1603 1604 LOG_DIS("muls.%c $r%u, $r%u\n", 1605 memsize_char(size), dc->op1, dc->op2); 1606 cris_cc_mask(dc, CC_MASK_NZV); 1607 cris_alu_alloc_temps(dc, size, t); 1608 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]); 1609 1610 cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4); 1611 cris_alu_free_temps(dc, size, t); 1612 return 2; 1613 } 1614 1615 static int dec_mulu_r(CPUCRISState *env, DisasContext *dc) 1616 { 1617 TCGv t[2]; 1618 int size = memsize_zz(dc); 1619 1620 LOG_DIS("mulu.%c $r%u, $r%u\n", 1621 memsize_char(size), dc->op1, dc->op2); 1622 cris_cc_mask(dc, CC_MASK_NZV); 1623 cris_alu_alloc_temps(dc, size, t); 1624 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1625 1626 cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4); 1627 cris_alu_alloc_temps(dc, size, t); 1628 return 2; 1629 } 1630 1631 1632 static int dec_dstep_r(CPUCRISState *env, DisasContext *dc) 1633 { 1634 LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2); 1635 cris_cc_mask(dc, CC_MASK_NZ); 1636 cris_alu(dc, CC_OP_DSTEP, 1637 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4); 1638 return 2; 1639 } 1640 1641 static int dec_xor_r(CPUCRISState *env, DisasContext *dc) 1642 { 1643 TCGv t[2]; 1644 int size = memsize_zz(dc); 1645 LOG_DIS("xor.%c $r%u, $r%u\n", 1646 memsize_char(size), dc->op1, dc->op2); 1647 BUG_ON(size != 4); /* xor is dword. */ 1648 cris_cc_mask(dc, CC_MASK_NZ); 1649 cris_alu_alloc_temps(dc, size, t); 1650 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1651 1652 cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4); 1653 cris_alu_free_temps(dc, size, t); 1654 return 2; 1655 } 1656 1657 static int dec_bound_r(CPUCRISState *env, DisasContext *dc) 1658 { 1659 TCGv l0; 1660 int size = memsize_zz(dc); 1661 LOG_DIS("bound.%c $r%u, $r%u\n", 1662 memsize_char(size), dc->op1, dc->op2); 1663 cris_cc_mask(dc, CC_MASK_NZ); 1664 l0 = tcg_temp_local_new(); 1665 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0); 1666 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4); 1667 tcg_temp_free(l0); 1668 return 2; 1669 } 1670 1671 static int dec_cmp_r(CPUCRISState *env, DisasContext *dc) 1672 { 1673 TCGv t[2]; 1674 int size = memsize_zz(dc); 1675 LOG_DIS("cmp.%c $r%u, $r%u\n", 1676 memsize_char(size), dc->op1, dc->op2); 1677 cris_cc_mask(dc, CC_MASK_NZVC); 1678 cris_alu_alloc_temps(dc, size, t); 1679 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1680 1681 cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size); 1682 cris_alu_free_temps(dc, size, t); 1683 return 2; 1684 } 1685 1686 static int dec_abs_r(CPUCRISState *env, DisasContext *dc) 1687 { 1688 TCGv t0; 1689 1690 LOG_DIS("abs $r%u, $r%u\n", 1691 dc->op1, dc->op2); 1692 cris_cc_mask(dc, CC_MASK_NZ); 1693 1694 t0 = tcg_temp_new(); 1695 tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31); 1696 tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0); 1697 tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0); 1698 tcg_temp_free(t0); 1699 1700 cris_alu(dc, CC_OP_MOVE, 1701 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4); 1702 return 2; 1703 } 1704 1705 static int dec_add_r(CPUCRISState *env, DisasContext *dc) 1706 { 1707 TCGv t[2]; 1708 int size = memsize_zz(dc); 1709 LOG_DIS("add.%c $r%u, $r%u\n", 1710 memsize_char(size), dc->op1, dc->op2); 1711 cris_cc_mask(dc, CC_MASK_NZVC); 1712 cris_alu_alloc_temps(dc, size, t); 1713 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1714 1715 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size); 1716 cris_alu_free_temps(dc, size, t); 1717 return 2; 1718 } 1719 1720 static int dec_addc_r(CPUCRISState *env, DisasContext *dc) 1721 { 1722 LOG_DIS("addc $r%u, $r%u\n", 1723 dc->op1, dc->op2); 1724 cris_evaluate_flags(dc); 1725 /* Set for this insn. */ 1726 dc->flagx_known = 1; 1727 dc->flags_x = X_FLAG; 1728 1729 cris_cc_mask(dc, CC_MASK_NZVC); 1730 cris_alu(dc, CC_OP_ADDC, 1731 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4); 1732 return 2; 1733 } 1734 1735 static int dec_mcp_r(CPUCRISState *env, DisasContext *dc) 1736 { 1737 LOG_DIS("mcp $p%u, $r%u\n", 1738 dc->op2, dc->op1); 1739 cris_evaluate_flags(dc); 1740 cris_cc_mask(dc, CC_MASK_RNZV); 1741 cris_alu(dc, CC_OP_MCP, 1742 cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4); 1743 return 2; 1744 } 1745 1746 #if DISAS_CRIS 1747 static char * swapmode_name(int mode, char *modename) { 1748 int i = 0; 1749 if (mode & 8) { 1750 modename[i++] = 'n'; 1751 } 1752 if (mode & 4) { 1753 modename[i++] = 'w'; 1754 } 1755 if (mode & 2) { 1756 modename[i++] = 'b'; 1757 } 1758 if (mode & 1) { 1759 modename[i++] = 'r'; 1760 } 1761 modename[i++] = 0; 1762 return modename; 1763 } 1764 #endif 1765 1766 static int dec_swap_r(CPUCRISState *env, DisasContext *dc) 1767 { 1768 TCGv t0; 1769 #if DISAS_CRIS 1770 char modename[4]; 1771 #endif 1772 LOG_DIS("swap%s $r%u\n", 1773 swapmode_name(dc->op2, modename), dc->op1); 1774 1775 cris_cc_mask(dc, CC_MASK_NZ); 1776 t0 = tcg_temp_new(); 1777 tcg_gen_mov_tl(t0, cpu_R[dc->op1]); 1778 if (dc->op2 & 8) { 1779 tcg_gen_not_tl(t0, t0); 1780 } 1781 if (dc->op2 & 4) { 1782 t_gen_swapw(t0, t0); 1783 } 1784 if (dc->op2 & 2) { 1785 t_gen_swapb(t0, t0); 1786 } 1787 if (dc->op2 & 1) { 1788 t_gen_swapr(t0, t0); 1789 } 1790 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4); 1791 tcg_temp_free(t0); 1792 return 2; 1793 } 1794 1795 static int dec_or_r(CPUCRISState *env, DisasContext *dc) 1796 { 1797 TCGv t[2]; 1798 int size = memsize_zz(dc); 1799 LOG_DIS("or.%c $r%u, $r%u\n", 1800 memsize_char(size), dc->op1, dc->op2); 1801 cris_cc_mask(dc, CC_MASK_NZ); 1802 cris_alu_alloc_temps(dc, size, t); 1803 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1804 cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size); 1805 cris_alu_free_temps(dc, size, t); 1806 return 2; 1807 } 1808 1809 static int dec_addi_r(CPUCRISState *env, DisasContext *dc) 1810 { 1811 TCGv t0; 1812 LOG_DIS("addi.%c $r%u, $r%u\n", 1813 memsize_char(memsize_zz(dc)), dc->op2, dc->op1); 1814 cris_cc_mask(dc, 0); 1815 t0 = tcg_temp_new(); 1816 tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize)); 1817 tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0); 1818 tcg_temp_free(t0); 1819 return 2; 1820 } 1821 1822 static int dec_addi_acr(CPUCRISState *env, DisasContext *dc) 1823 { 1824 TCGv t0; 1825 LOG_DIS("addi.%c $r%u, $r%u, $acr\n", 1826 memsize_char(memsize_zz(dc)), dc->op2, dc->op1); 1827 cris_cc_mask(dc, 0); 1828 t0 = tcg_temp_new(); 1829 tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize)); 1830 tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0); 1831 tcg_temp_free(t0); 1832 return 2; 1833 } 1834 1835 static int dec_neg_r(CPUCRISState *env, DisasContext *dc) 1836 { 1837 TCGv t[2]; 1838 int size = memsize_zz(dc); 1839 LOG_DIS("neg.%c $r%u, $r%u\n", 1840 memsize_char(size), dc->op1, dc->op2); 1841 cris_cc_mask(dc, CC_MASK_NZVC); 1842 cris_alu_alloc_temps(dc, size, t); 1843 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1844 1845 cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size); 1846 cris_alu_free_temps(dc, size, t); 1847 return 2; 1848 } 1849 1850 static int dec_btst_r(CPUCRISState *env, DisasContext *dc) 1851 { 1852 LOG_DIS("btst $r%u, $r%u\n", 1853 dc->op1, dc->op2); 1854 cris_cc_mask(dc, CC_MASK_NZ); 1855 cris_evaluate_flags(dc); 1856 gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2], 1857 cpu_R[dc->op1], cpu_PR[PR_CCS]); 1858 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], 1859 cpu_R[dc->op2], cpu_R[dc->op2], 4); 1860 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 1861 dc->flags_uptodate = 1; 1862 return 2; 1863 } 1864 1865 static int dec_sub_r(CPUCRISState *env, DisasContext *dc) 1866 { 1867 TCGv t[2]; 1868 int size = memsize_zz(dc); 1869 LOG_DIS("sub.%c $r%u, $r%u\n", 1870 memsize_char(size), dc->op1, dc->op2); 1871 cris_cc_mask(dc, CC_MASK_NZVC); 1872 cris_alu_alloc_temps(dc, size, t); 1873 dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]); 1874 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size); 1875 cris_alu_free_temps(dc, size, t); 1876 return 2; 1877 } 1878 1879 /* Zero extension. From size to dword. */ 1880 static int dec_movu_r(CPUCRISState *env, DisasContext *dc) 1881 { 1882 TCGv t0; 1883 int size = memsize_z(dc); 1884 LOG_DIS("movu.%c $r%u, $r%u\n", 1885 memsize_char(size), 1886 dc->op1, dc->op2); 1887 1888 cris_cc_mask(dc, CC_MASK_NZ); 1889 t0 = tcg_temp_new(); 1890 dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0); 1891 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4); 1892 tcg_temp_free(t0); 1893 return 2; 1894 } 1895 1896 /* Sign extension. From size to dword. */ 1897 static int dec_movs_r(CPUCRISState *env, DisasContext *dc) 1898 { 1899 TCGv t0; 1900 int size = memsize_z(dc); 1901 LOG_DIS("movs.%c $r%u, $r%u\n", 1902 memsize_char(size), 1903 dc->op1, dc->op2); 1904 1905 cris_cc_mask(dc, CC_MASK_NZ); 1906 t0 = tcg_temp_new(); 1907 /* Size can only be qi or hi. */ 1908 t_gen_sext(t0, cpu_R[dc->op1], size); 1909 cris_alu(dc, CC_OP_MOVE, 1910 cpu_R[dc->op2], cpu_R[dc->op1], t0, 4); 1911 tcg_temp_free(t0); 1912 return 2; 1913 } 1914 1915 /* zero extension. From size to dword. */ 1916 static int dec_addu_r(CPUCRISState *env, DisasContext *dc) 1917 { 1918 TCGv t0; 1919 int size = memsize_z(dc); 1920 LOG_DIS("addu.%c $r%u, $r%u\n", 1921 memsize_char(size), 1922 dc->op1, dc->op2); 1923 1924 cris_cc_mask(dc, CC_MASK_NZVC); 1925 t0 = tcg_temp_new(); 1926 /* Size can only be qi or hi. */ 1927 t_gen_zext(t0, cpu_R[dc->op1], size); 1928 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4); 1929 tcg_temp_free(t0); 1930 return 2; 1931 } 1932 1933 /* Sign extension. From size to dword. */ 1934 static int dec_adds_r(CPUCRISState *env, DisasContext *dc) 1935 { 1936 TCGv t0; 1937 int size = memsize_z(dc); 1938 LOG_DIS("adds.%c $r%u, $r%u\n", 1939 memsize_char(size), 1940 dc->op1, dc->op2); 1941 1942 cris_cc_mask(dc, CC_MASK_NZVC); 1943 t0 = tcg_temp_new(); 1944 /* Size can only be qi or hi. */ 1945 t_gen_sext(t0, cpu_R[dc->op1], size); 1946 cris_alu(dc, CC_OP_ADD, 1947 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4); 1948 tcg_temp_free(t0); 1949 return 2; 1950 } 1951 1952 /* Zero extension. From size to dword. */ 1953 static int dec_subu_r(CPUCRISState *env, DisasContext *dc) 1954 { 1955 TCGv t0; 1956 int size = memsize_z(dc); 1957 LOG_DIS("subu.%c $r%u, $r%u\n", 1958 memsize_char(size), 1959 dc->op1, dc->op2); 1960 1961 cris_cc_mask(dc, CC_MASK_NZVC); 1962 t0 = tcg_temp_new(); 1963 /* Size can only be qi or hi. */ 1964 t_gen_zext(t0, cpu_R[dc->op1], size); 1965 cris_alu(dc, CC_OP_SUB, 1966 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4); 1967 tcg_temp_free(t0); 1968 return 2; 1969 } 1970 1971 /* Sign extension. From size to dword. */ 1972 static int dec_subs_r(CPUCRISState *env, DisasContext *dc) 1973 { 1974 TCGv t0; 1975 int size = memsize_z(dc); 1976 LOG_DIS("subs.%c $r%u, $r%u\n", 1977 memsize_char(size), 1978 dc->op1, dc->op2); 1979 1980 cris_cc_mask(dc, CC_MASK_NZVC); 1981 t0 = tcg_temp_new(); 1982 /* Size can only be qi or hi. */ 1983 t_gen_sext(t0, cpu_R[dc->op1], size); 1984 cris_alu(dc, CC_OP_SUB, 1985 cpu_R[dc->op2], cpu_R[dc->op2], t0, 4); 1986 tcg_temp_free(t0); 1987 return 2; 1988 } 1989 1990 static int dec_setclrf(CPUCRISState *env, DisasContext *dc) 1991 { 1992 uint32_t flags; 1993 int set = (~dc->opcode >> 2) & 1; 1994 1995 1996 flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4) 1997 | EXTRACT_FIELD(dc->ir, 0, 3); 1998 if (set && flags == 0) { 1999 LOG_DIS("nop\n"); 2000 return 2; 2001 } else if (!set && (flags & 0x20)) { 2002 LOG_DIS("di\n"); 2003 } else { 2004 LOG_DIS("%sf %x\n", set ? "set" : "clr", flags); 2005 } 2006 2007 /* User space is not allowed to touch these. Silently ignore. */ 2008 if (dc->tb_flags & U_FLAG) { 2009 flags &= ~(S_FLAG | I_FLAG | U_FLAG); 2010 } 2011 2012 if (flags & X_FLAG) { 2013 dc->flagx_known = 1; 2014 if (set) { 2015 dc->flags_x = X_FLAG; 2016 } else { 2017 dc->flags_x = 0; 2018 } 2019 } 2020 2021 /* Break the TB if any of the SPI flag changes. */ 2022 if (flags & (P_FLAG | S_FLAG)) { 2023 tcg_gen_movi_tl(env_pc, dc->pc + 2); 2024 dc->is_jmp = DISAS_UPDATE; 2025 dc->cpustate_changed = 1; 2026 } 2027 2028 /* For the I flag, only act on posedge. */ 2029 if ((flags & I_FLAG)) { 2030 tcg_gen_movi_tl(env_pc, dc->pc + 2); 2031 dc->is_jmp = DISAS_UPDATE; 2032 dc->cpustate_changed = 1; 2033 } 2034 2035 2036 /* Simply decode the flags. */ 2037 cris_evaluate_flags(dc); 2038 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 2039 cris_update_cc_x(dc); 2040 tcg_gen_movi_tl(cc_op, dc->cc_op); 2041 2042 if (set) { 2043 if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) { 2044 /* Enter user mode. */ 2045 t_gen_mov_env_TN(ksp, cpu_R[R_SP]); 2046 tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]); 2047 dc->cpustate_changed = 1; 2048 } 2049 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags); 2050 } else { 2051 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags); 2052 } 2053 2054 dc->flags_uptodate = 1; 2055 dc->clear_x = 0; 2056 return 2; 2057 } 2058 2059 static int dec_move_rs(CPUCRISState *env, DisasContext *dc) 2060 { 2061 LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2); 2062 cris_cc_mask(dc, 0); 2063 gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2), 2064 tcg_const_tl(dc->op1)); 2065 return 2; 2066 } 2067 static int dec_move_sr(CPUCRISState *env, DisasContext *dc) 2068 { 2069 LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1); 2070 cris_cc_mask(dc, 0); 2071 gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1), 2072 tcg_const_tl(dc->op2)); 2073 return 2; 2074 } 2075 2076 static int dec_move_rp(CPUCRISState *env, DisasContext *dc) 2077 { 2078 TCGv t[2]; 2079 LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2); 2080 cris_cc_mask(dc, 0); 2081 2082 t[0] = tcg_temp_new(); 2083 if (dc->op2 == PR_CCS) { 2084 cris_evaluate_flags(dc); 2085 tcg_gen_mov_tl(t[0], cpu_R[dc->op1]); 2086 if (dc->tb_flags & U_FLAG) { 2087 t[1] = tcg_temp_new(); 2088 /* User space is not allowed to touch all flags. */ 2089 tcg_gen_andi_tl(t[0], t[0], 0x39f); 2090 tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f); 2091 tcg_gen_or_tl(t[0], t[1], t[0]); 2092 tcg_temp_free(t[1]); 2093 } 2094 } else { 2095 tcg_gen_mov_tl(t[0], cpu_R[dc->op1]); 2096 } 2097 2098 t_gen_mov_preg_TN(dc, dc->op2, t[0]); 2099 if (dc->op2 == PR_CCS) { 2100 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 2101 dc->flags_uptodate = 1; 2102 } 2103 tcg_temp_free(t[0]); 2104 return 2; 2105 } 2106 static int dec_move_pr(CPUCRISState *env, DisasContext *dc) 2107 { 2108 TCGv t0; 2109 LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1); 2110 cris_cc_mask(dc, 0); 2111 2112 if (dc->op2 == PR_CCS) { 2113 cris_evaluate_flags(dc); 2114 } 2115 2116 if (dc->op2 == PR_DZ) { 2117 tcg_gen_movi_tl(cpu_R[dc->op1], 0); 2118 } else { 2119 t0 = tcg_temp_new(); 2120 t_gen_mov_TN_preg(t0, dc->op2); 2121 cris_alu(dc, CC_OP_MOVE, 2122 cpu_R[dc->op1], cpu_R[dc->op1], t0, 2123 preg_sizes[dc->op2]); 2124 tcg_temp_free(t0); 2125 } 2126 return 2; 2127 } 2128 2129 static int dec_move_mr(CPUCRISState *env, DisasContext *dc) 2130 { 2131 int memsize = memsize_zz(dc); 2132 int insn_len; 2133 LOG_DIS("move.%c [$r%u%s, $r%u\n", 2134 memsize_char(memsize), 2135 dc->op1, dc->postinc ? "+]" : "]", 2136 dc->op2); 2137 2138 if (memsize == 4) { 2139 insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]); 2140 cris_cc_mask(dc, CC_MASK_NZ); 2141 cris_update_cc_op(dc, CC_OP_MOVE, 4); 2142 cris_update_cc_x(dc); 2143 cris_update_result(dc, cpu_R[dc->op2]); 2144 } else { 2145 TCGv t0; 2146 2147 t0 = tcg_temp_new(); 2148 insn_len = dec_prep_move_m(env, dc, 0, memsize, t0); 2149 cris_cc_mask(dc, CC_MASK_NZ); 2150 cris_alu(dc, CC_OP_MOVE, 2151 cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize); 2152 tcg_temp_free(t0); 2153 } 2154 do_postinc(dc, memsize); 2155 return insn_len; 2156 } 2157 2158 static inline void cris_alu_m_alloc_temps(TCGv *t) 2159 { 2160 t[0] = tcg_temp_new(); 2161 t[1] = tcg_temp_new(); 2162 } 2163 2164 static inline void cris_alu_m_free_temps(TCGv *t) 2165 { 2166 tcg_temp_free(t[0]); 2167 tcg_temp_free(t[1]); 2168 } 2169 2170 static int dec_movs_m(CPUCRISState *env, DisasContext *dc) 2171 { 2172 TCGv t[2]; 2173 int memsize = memsize_z(dc); 2174 int insn_len; 2175 LOG_DIS("movs.%c [$r%u%s, $r%u\n", 2176 memsize_char(memsize), 2177 dc->op1, dc->postinc ? "+]" : "]", 2178 dc->op2); 2179 2180 cris_alu_m_alloc_temps(t); 2181 /* sign extend. */ 2182 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]); 2183 cris_cc_mask(dc, CC_MASK_NZ); 2184 cris_alu(dc, CC_OP_MOVE, 2185 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4); 2186 do_postinc(dc, memsize); 2187 cris_alu_m_free_temps(t); 2188 return insn_len; 2189 } 2190 2191 static int dec_addu_m(CPUCRISState *env, DisasContext *dc) 2192 { 2193 TCGv t[2]; 2194 int memsize = memsize_z(dc); 2195 int insn_len; 2196 LOG_DIS("addu.%c [$r%u%s, $r%u\n", 2197 memsize_char(memsize), 2198 dc->op1, dc->postinc ? "+]" : "]", 2199 dc->op2); 2200 2201 cris_alu_m_alloc_temps(t); 2202 /* sign extend. */ 2203 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2204 cris_cc_mask(dc, CC_MASK_NZVC); 2205 cris_alu(dc, CC_OP_ADD, 2206 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4); 2207 do_postinc(dc, memsize); 2208 cris_alu_m_free_temps(t); 2209 return insn_len; 2210 } 2211 2212 static int dec_adds_m(CPUCRISState *env, DisasContext *dc) 2213 { 2214 TCGv t[2]; 2215 int memsize = memsize_z(dc); 2216 int insn_len; 2217 LOG_DIS("adds.%c [$r%u%s, $r%u\n", 2218 memsize_char(memsize), 2219 dc->op1, dc->postinc ? "+]" : "]", 2220 dc->op2); 2221 2222 cris_alu_m_alloc_temps(t); 2223 /* sign extend. */ 2224 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]); 2225 cris_cc_mask(dc, CC_MASK_NZVC); 2226 cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4); 2227 do_postinc(dc, memsize); 2228 cris_alu_m_free_temps(t); 2229 return insn_len; 2230 } 2231 2232 static int dec_subu_m(CPUCRISState *env, DisasContext *dc) 2233 { 2234 TCGv t[2]; 2235 int memsize = memsize_z(dc); 2236 int insn_len; 2237 LOG_DIS("subu.%c [$r%u%s, $r%u\n", 2238 memsize_char(memsize), 2239 dc->op1, dc->postinc ? "+]" : "]", 2240 dc->op2); 2241 2242 cris_alu_m_alloc_temps(t); 2243 /* sign extend. */ 2244 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2245 cris_cc_mask(dc, CC_MASK_NZVC); 2246 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4); 2247 do_postinc(dc, memsize); 2248 cris_alu_m_free_temps(t); 2249 return insn_len; 2250 } 2251 2252 static int dec_subs_m(CPUCRISState *env, DisasContext *dc) 2253 { 2254 TCGv t[2]; 2255 int memsize = memsize_z(dc); 2256 int insn_len; 2257 LOG_DIS("subs.%c [$r%u%s, $r%u\n", 2258 memsize_char(memsize), 2259 dc->op1, dc->postinc ? "+]" : "]", 2260 dc->op2); 2261 2262 cris_alu_m_alloc_temps(t); 2263 /* sign extend. */ 2264 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]); 2265 cris_cc_mask(dc, CC_MASK_NZVC); 2266 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4); 2267 do_postinc(dc, memsize); 2268 cris_alu_m_free_temps(t); 2269 return insn_len; 2270 } 2271 2272 static int dec_movu_m(CPUCRISState *env, DisasContext *dc) 2273 { 2274 TCGv t[2]; 2275 int memsize = memsize_z(dc); 2276 int insn_len; 2277 2278 LOG_DIS("movu.%c [$r%u%s, $r%u\n", 2279 memsize_char(memsize), 2280 dc->op1, dc->postinc ? "+]" : "]", 2281 dc->op2); 2282 2283 cris_alu_m_alloc_temps(t); 2284 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2285 cris_cc_mask(dc, CC_MASK_NZ); 2286 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4); 2287 do_postinc(dc, memsize); 2288 cris_alu_m_free_temps(t); 2289 return insn_len; 2290 } 2291 2292 static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc) 2293 { 2294 TCGv t[2]; 2295 int memsize = memsize_z(dc); 2296 int insn_len; 2297 LOG_DIS("cmpu.%c [$r%u%s, $r%u\n", 2298 memsize_char(memsize), 2299 dc->op1, dc->postinc ? "+]" : "]", 2300 dc->op2); 2301 2302 cris_alu_m_alloc_temps(t); 2303 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2304 cris_cc_mask(dc, CC_MASK_NZVC); 2305 cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4); 2306 do_postinc(dc, memsize); 2307 cris_alu_m_free_temps(t); 2308 return insn_len; 2309 } 2310 2311 static int dec_cmps_m(CPUCRISState *env, DisasContext *dc) 2312 { 2313 TCGv t[2]; 2314 int memsize = memsize_z(dc); 2315 int insn_len; 2316 LOG_DIS("cmps.%c [$r%u%s, $r%u\n", 2317 memsize_char(memsize), 2318 dc->op1, dc->postinc ? "+]" : "]", 2319 dc->op2); 2320 2321 cris_alu_m_alloc_temps(t); 2322 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]); 2323 cris_cc_mask(dc, CC_MASK_NZVC); 2324 cris_alu(dc, CC_OP_CMP, 2325 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 2326 memsize_zz(dc)); 2327 do_postinc(dc, memsize); 2328 cris_alu_m_free_temps(t); 2329 return insn_len; 2330 } 2331 2332 static int dec_cmp_m(CPUCRISState *env, DisasContext *dc) 2333 { 2334 TCGv t[2]; 2335 int memsize = memsize_zz(dc); 2336 int insn_len; 2337 LOG_DIS("cmp.%c [$r%u%s, $r%u\n", 2338 memsize_char(memsize), 2339 dc->op1, dc->postinc ? "+]" : "]", 2340 dc->op2); 2341 2342 cris_alu_m_alloc_temps(t); 2343 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2344 cris_cc_mask(dc, CC_MASK_NZVC); 2345 cris_alu(dc, CC_OP_CMP, 2346 cpu_R[dc->op2], cpu_R[dc->op2], t[1], 2347 memsize_zz(dc)); 2348 do_postinc(dc, memsize); 2349 cris_alu_m_free_temps(t); 2350 return insn_len; 2351 } 2352 2353 static int dec_test_m(CPUCRISState *env, DisasContext *dc) 2354 { 2355 TCGv t[2]; 2356 int memsize = memsize_zz(dc); 2357 int insn_len; 2358 LOG_DIS("test.%c [$r%u%s] op2=%x\n", 2359 memsize_char(memsize), 2360 dc->op1, dc->postinc ? "+]" : "]", 2361 dc->op2); 2362 2363 cris_evaluate_flags(dc); 2364 2365 cris_alu_m_alloc_temps(t); 2366 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2367 cris_cc_mask(dc, CC_MASK_NZ); 2368 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3); 2369 2370 cris_alu(dc, CC_OP_CMP, 2371 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc)); 2372 do_postinc(dc, memsize); 2373 cris_alu_m_free_temps(t); 2374 return insn_len; 2375 } 2376 2377 static int dec_and_m(CPUCRISState *env, DisasContext *dc) 2378 { 2379 TCGv t[2]; 2380 int memsize = memsize_zz(dc); 2381 int insn_len; 2382 LOG_DIS("and.%c [$r%u%s, $r%u\n", 2383 memsize_char(memsize), 2384 dc->op1, dc->postinc ? "+]" : "]", 2385 dc->op2); 2386 2387 cris_alu_m_alloc_temps(t); 2388 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2389 cris_cc_mask(dc, CC_MASK_NZ); 2390 cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc)); 2391 do_postinc(dc, memsize); 2392 cris_alu_m_free_temps(t); 2393 return insn_len; 2394 } 2395 2396 static int dec_add_m(CPUCRISState *env, DisasContext *dc) 2397 { 2398 TCGv t[2]; 2399 int memsize = memsize_zz(dc); 2400 int insn_len; 2401 LOG_DIS("add.%c [$r%u%s, $r%u\n", 2402 memsize_char(memsize), 2403 dc->op1, dc->postinc ? "+]" : "]", 2404 dc->op2); 2405 2406 cris_alu_m_alloc_temps(t); 2407 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2408 cris_cc_mask(dc, CC_MASK_NZVC); 2409 cris_alu(dc, CC_OP_ADD, 2410 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc)); 2411 do_postinc(dc, memsize); 2412 cris_alu_m_free_temps(t); 2413 return insn_len; 2414 } 2415 2416 static int dec_addo_m(CPUCRISState *env, DisasContext *dc) 2417 { 2418 TCGv t[2]; 2419 int memsize = memsize_zz(dc); 2420 int insn_len; 2421 LOG_DIS("add.%c [$r%u%s, $r%u\n", 2422 memsize_char(memsize), 2423 dc->op1, dc->postinc ? "+]" : "]", 2424 dc->op2); 2425 2426 cris_alu_m_alloc_temps(t); 2427 insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]); 2428 cris_cc_mask(dc, 0); 2429 cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4); 2430 do_postinc(dc, memsize); 2431 cris_alu_m_free_temps(t); 2432 return insn_len; 2433 } 2434 2435 static int dec_bound_m(CPUCRISState *env, DisasContext *dc) 2436 { 2437 TCGv l[2]; 2438 int memsize = memsize_zz(dc); 2439 int insn_len; 2440 LOG_DIS("bound.%c [$r%u%s, $r%u\n", 2441 memsize_char(memsize), 2442 dc->op1, dc->postinc ? "+]" : "]", 2443 dc->op2); 2444 2445 l[0] = tcg_temp_local_new(); 2446 l[1] = tcg_temp_local_new(); 2447 insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]); 2448 cris_cc_mask(dc, CC_MASK_NZ); 2449 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4); 2450 do_postinc(dc, memsize); 2451 tcg_temp_free(l[0]); 2452 tcg_temp_free(l[1]); 2453 return insn_len; 2454 } 2455 2456 static int dec_addc_mr(CPUCRISState *env, DisasContext *dc) 2457 { 2458 TCGv t[2]; 2459 int insn_len = 2; 2460 LOG_DIS("addc [$r%u%s, $r%u\n", 2461 dc->op1, dc->postinc ? "+]" : "]", 2462 dc->op2); 2463 2464 cris_evaluate_flags(dc); 2465 2466 /* Set for this insn. */ 2467 dc->flagx_known = 1; 2468 dc->flags_x = X_FLAG; 2469 2470 cris_alu_m_alloc_temps(t); 2471 insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]); 2472 cris_cc_mask(dc, CC_MASK_NZVC); 2473 cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4); 2474 do_postinc(dc, 4); 2475 cris_alu_m_free_temps(t); 2476 return insn_len; 2477 } 2478 2479 static int dec_sub_m(CPUCRISState *env, DisasContext *dc) 2480 { 2481 TCGv t[2]; 2482 int memsize = memsize_zz(dc); 2483 int insn_len; 2484 LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n", 2485 memsize_char(memsize), 2486 dc->op1, dc->postinc ? "+]" : "]", 2487 dc->op2, dc->ir, dc->zzsize); 2488 2489 cris_alu_m_alloc_temps(t); 2490 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2491 cris_cc_mask(dc, CC_MASK_NZVC); 2492 cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize); 2493 do_postinc(dc, memsize); 2494 cris_alu_m_free_temps(t); 2495 return insn_len; 2496 } 2497 2498 static int dec_or_m(CPUCRISState *env, DisasContext *dc) 2499 { 2500 TCGv t[2]; 2501 int memsize = memsize_zz(dc); 2502 int insn_len; 2503 LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n", 2504 memsize_char(memsize), 2505 dc->op1, dc->postinc ? "+]" : "]", 2506 dc->op2, dc->pc); 2507 2508 cris_alu_m_alloc_temps(t); 2509 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2510 cris_cc_mask(dc, CC_MASK_NZ); 2511 cris_alu(dc, CC_OP_OR, 2512 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc)); 2513 do_postinc(dc, memsize); 2514 cris_alu_m_free_temps(t); 2515 return insn_len; 2516 } 2517 2518 static int dec_move_mp(CPUCRISState *env, DisasContext *dc) 2519 { 2520 TCGv t[2]; 2521 int memsize = memsize_zz(dc); 2522 int insn_len = 2; 2523 2524 LOG_DIS("move.%c [$r%u%s, $p%u\n", 2525 memsize_char(memsize), 2526 dc->op1, 2527 dc->postinc ? "+]" : "]", 2528 dc->op2); 2529 2530 cris_alu_m_alloc_temps(t); 2531 insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]); 2532 cris_cc_mask(dc, 0); 2533 if (dc->op2 == PR_CCS) { 2534 cris_evaluate_flags(dc); 2535 if (dc->tb_flags & U_FLAG) { 2536 /* User space is not allowed to touch all flags. */ 2537 tcg_gen_andi_tl(t[1], t[1], 0x39f); 2538 tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f); 2539 tcg_gen_or_tl(t[1], t[0], t[1]); 2540 } 2541 } 2542 2543 t_gen_mov_preg_TN(dc, dc->op2, t[1]); 2544 2545 do_postinc(dc, memsize); 2546 cris_alu_m_free_temps(t); 2547 return insn_len; 2548 } 2549 2550 static int dec_move_pm(CPUCRISState *env, DisasContext *dc) 2551 { 2552 TCGv t0; 2553 int memsize; 2554 2555 memsize = preg_sizes[dc->op2]; 2556 2557 LOG_DIS("move.%c $p%u, [$r%u%s\n", 2558 memsize_char(memsize), 2559 dc->op2, dc->op1, dc->postinc ? "+]" : "]"); 2560 2561 /* prepare store. Address in T0, value in T1. */ 2562 if (dc->op2 == PR_CCS) { 2563 cris_evaluate_flags(dc); 2564 } 2565 t0 = tcg_temp_new(); 2566 t_gen_mov_TN_preg(t0, dc->op2); 2567 cris_flush_cc_state(dc); 2568 gen_store(dc, cpu_R[dc->op1], t0, memsize); 2569 tcg_temp_free(t0); 2570 2571 cris_cc_mask(dc, 0); 2572 if (dc->postinc) { 2573 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize); 2574 } 2575 return 2; 2576 } 2577 2578 static int dec_movem_mr(CPUCRISState *env, DisasContext *dc) 2579 { 2580 TCGv_i64 tmp[16]; 2581 TCGv tmp32; 2582 TCGv addr; 2583 int i; 2584 int nr = dc->op2 + 1; 2585 2586 LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1, 2587 dc->postinc ? "+]" : "]", dc->op2); 2588 2589 addr = tcg_temp_new(); 2590 /* There are probably better ways of doing this. */ 2591 cris_flush_cc_state(dc); 2592 for (i = 0; i < (nr >> 1); i++) { 2593 tmp[i] = tcg_temp_new_i64(); 2594 tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8); 2595 gen_load64(dc, tmp[i], addr); 2596 } 2597 if (nr & 1) { 2598 tmp32 = tcg_temp_new_i32(); 2599 tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8); 2600 gen_load(dc, tmp32, addr, 4, 0); 2601 } else { 2602 TCGV_UNUSED(tmp32); 2603 } 2604 tcg_temp_free(addr); 2605 2606 for (i = 0; i < (nr >> 1); i++) { 2607 tcg_gen_extrl_i64_i32(cpu_R[i * 2], tmp[i]); 2608 tcg_gen_shri_i64(tmp[i], tmp[i], 32); 2609 tcg_gen_extrl_i64_i32(cpu_R[i * 2 + 1], tmp[i]); 2610 tcg_temp_free_i64(tmp[i]); 2611 } 2612 if (nr & 1) { 2613 tcg_gen_mov_tl(cpu_R[dc->op2], tmp32); 2614 tcg_temp_free(tmp32); 2615 } 2616 2617 /* writeback the updated pointer value. */ 2618 if (dc->postinc) { 2619 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4); 2620 } 2621 2622 /* gen_load might want to evaluate the previous insns flags. */ 2623 cris_cc_mask(dc, 0); 2624 return 2; 2625 } 2626 2627 static int dec_movem_rm(CPUCRISState *env, DisasContext *dc) 2628 { 2629 TCGv tmp; 2630 TCGv addr; 2631 int i; 2632 2633 LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1, 2634 dc->postinc ? "+]" : "]"); 2635 2636 cris_flush_cc_state(dc); 2637 2638 tmp = tcg_temp_new(); 2639 addr = tcg_temp_new(); 2640 tcg_gen_movi_tl(tmp, 4); 2641 tcg_gen_mov_tl(addr, cpu_R[dc->op1]); 2642 for (i = 0; i <= dc->op2; i++) { 2643 /* Displace addr. */ 2644 /* Perform the store. */ 2645 gen_store(dc, addr, cpu_R[i], 4); 2646 tcg_gen_add_tl(addr, addr, tmp); 2647 } 2648 if (dc->postinc) { 2649 tcg_gen_mov_tl(cpu_R[dc->op1], addr); 2650 } 2651 cris_cc_mask(dc, 0); 2652 tcg_temp_free(tmp); 2653 tcg_temp_free(addr); 2654 return 2; 2655 } 2656 2657 static int dec_move_rm(CPUCRISState *env, DisasContext *dc) 2658 { 2659 int memsize; 2660 2661 memsize = memsize_zz(dc); 2662 2663 LOG_DIS("move.%c $r%u, [$r%u]\n", 2664 memsize_char(memsize), dc->op2, dc->op1); 2665 2666 /* prepare store. */ 2667 cris_flush_cc_state(dc); 2668 gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize); 2669 2670 if (dc->postinc) { 2671 tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize); 2672 } 2673 cris_cc_mask(dc, 0); 2674 return 2; 2675 } 2676 2677 static int dec_lapcq(CPUCRISState *env, DisasContext *dc) 2678 { 2679 LOG_DIS("lapcq %x, $r%u\n", 2680 dc->pc + dc->op1*2, dc->op2); 2681 cris_cc_mask(dc, 0); 2682 tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2); 2683 return 2; 2684 } 2685 2686 static int dec_lapc_im(CPUCRISState *env, DisasContext *dc) 2687 { 2688 unsigned int rd; 2689 int32_t imm; 2690 int32_t pc; 2691 2692 rd = dc->op2; 2693 2694 cris_cc_mask(dc, 0); 2695 imm = cris_fetch(env, dc, dc->pc + 2, 4, 0); 2696 LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2); 2697 2698 pc = dc->pc; 2699 pc += imm; 2700 tcg_gen_movi_tl(cpu_R[rd], pc); 2701 return 6; 2702 } 2703 2704 /* Jump to special reg. */ 2705 static int dec_jump_p(CPUCRISState *env, DisasContext *dc) 2706 { 2707 LOG_DIS("jump $p%u\n", dc->op2); 2708 2709 if (dc->op2 == PR_CCS) { 2710 cris_evaluate_flags(dc); 2711 } 2712 t_gen_mov_TN_preg(env_btarget, dc->op2); 2713 /* rete will often have low bit set to indicate delayslot. */ 2714 tcg_gen_andi_tl(env_btarget, env_btarget, ~1); 2715 cris_cc_mask(dc, 0); 2716 cris_prepare_jmp(dc, JMP_INDIRECT); 2717 return 2; 2718 } 2719 2720 /* Jump and save. */ 2721 static int dec_jas_r(CPUCRISState *env, DisasContext *dc) 2722 { 2723 LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2); 2724 cris_cc_mask(dc, 0); 2725 /* Store the return address in Pd. */ 2726 tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]); 2727 if (dc->op2 > 15) { 2728 abort(); 2729 } 2730 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4)); 2731 2732 cris_prepare_jmp(dc, JMP_INDIRECT); 2733 return 2; 2734 } 2735 2736 static int dec_jas_im(CPUCRISState *env, DisasContext *dc) 2737 { 2738 uint32_t imm; 2739 2740 imm = cris_fetch(env, dc, dc->pc + 2, 4, 0); 2741 2742 LOG_DIS("jas 0x%x\n", imm); 2743 cris_cc_mask(dc, 0); 2744 /* Store the return address in Pd. */ 2745 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8)); 2746 2747 dc->jmp_pc = imm; 2748 cris_prepare_jmp(dc, JMP_DIRECT); 2749 return 6; 2750 } 2751 2752 static int dec_jasc_im(CPUCRISState *env, DisasContext *dc) 2753 { 2754 uint32_t imm; 2755 2756 imm = cris_fetch(env, dc, dc->pc + 2, 4, 0); 2757 2758 LOG_DIS("jasc 0x%x\n", imm); 2759 cris_cc_mask(dc, 0); 2760 /* Store the return address in Pd. */ 2761 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4)); 2762 2763 dc->jmp_pc = imm; 2764 cris_prepare_jmp(dc, JMP_DIRECT); 2765 return 6; 2766 } 2767 2768 static int dec_jasc_r(CPUCRISState *env, DisasContext *dc) 2769 { 2770 LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2); 2771 cris_cc_mask(dc, 0); 2772 /* Store the return address in Pd. */ 2773 tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]); 2774 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4)); 2775 cris_prepare_jmp(dc, JMP_INDIRECT); 2776 return 2; 2777 } 2778 2779 static int dec_bcc_im(CPUCRISState *env, DisasContext *dc) 2780 { 2781 int32_t offset; 2782 uint32_t cond = dc->op2; 2783 2784 offset = cris_fetch(env, dc, dc->pc + 2, 2, 1); 2785 2786 LOG_DIS("b%s %d pc=%x dst=%x\n", 2787 cc_name(cond), offset, 2788 dc->pc, dc->pc + offset); 2789 2790 cris_cc_mask(dc, 0); 2791 /* op2 holds the condition-code. */ 2792 cris_prepare_cc_branch(dc, offset, cond); 2793 return 4; 2794 } 2795 2796 static int dec_bas_im(CPUCRISState *env, DisasContext *dc) 2797 { 2798 int32_t simm; 2799 2800 simm = cris_fetch(env, dc, dc->pc + 2, 4, 0); 2801 2802 LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2); 2803 cris_cc_mask(dc, 0); 2804 /* Store the return address in Pd. */ 2805 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8)); 2806 2807 dc->jmp_pc = dc->pc + simm; 2808 cris_prepare_jmp(dc, JMP_DIRECT); 2809 return 6; 2810 } 2811 2812 static int dec_basc_im(CPUCRISState *env, DisasContext *dc) 2813 { 2814 int32_t simm; 2815 simm = cris_fetch(env, dc, dc->pc + 2, 4, 0); 2816 2817 LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2); 2818 cris_cc_mask(dc, 0); 2819 /* Store the return address in Pd. */ 2820 t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12)); 2821 2822 dc->jmp_pc = dc->pc + simm; 2823 cris_prepare_jmp(dc, JMP_DIRECT); 2824 return 6; 2825 } 2826 2827 static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc) 2828 { 2829 cris_cc_mask(dc, 0); 2830 2831 if (dc->op2 == 15) { 2832 tcg_gen_st_i32(tcg_const_i32(1), cpu_env, 2833 -offsetof(CRISCPU, env) + offsetof(CPUState, halted)); 2834 tcg_gen_movi_tl(env_pc, dc->pc + 2); 2835 t_gen_raise_exception(EXCP_HLT); 2836 return 2; 2837 } 2838 2839 switch (dc->op2 & 7) { 2840 case 2: 2841 /* rfe. */ 2842 LOG_DIS("rfe\n"); 2843 cris_evaluate_flags(dc); 2844 gen_helper_rfe(cpu_env); 2845 dc->is_jmp = DISAS_UPDATE; 2846 break; 2847 case 5: 2848 /* rfn. */ 2849 LOG_DIS("rfn\n"); 2850 cris_evaluate_flags(dc); 2851 gen_helper_rfn(cpu_env); 2852 dc->is_jmp = DISAS_UPDATE; 2853 break; 2854 case 6: 2855 LOG_DIS("break %d\n", dc->op1); 2856 cris_evaluate_flags(dc); 2857 /* break. */ 2858 tcg_gen_movi_tl(env_pc, dc->pc + 2); 2859 2860 /* Breaks start at 16 in the exception vector. */ 2861 t_gen_mov_env_TN(trap_vector, 2862 tcg_const_tl(dc->op1 + 16)); 2863 t_gen_raise_exception(EXCP_BREAK); 2864 dc->is_jmp = DISAS_UPDATE; 2865 break; 2866 default: 2867 printf("op2=%x\n", dc->op2); 2868 BUG(); 2869 break; 2870 2871 } 2872 return 2; 2873 } 2874 2875 static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc) 2876 { 2877 return 2; 2878 } 2879 2880 static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc) 2881 { 2882 return 2; 2883 } 2884 2885 static int dec_null(CPUCRISState *env, DisasContext *dc) 2886 { 2887 printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n", 2888 dc->pc, dc->opcode, dc->op1, dc->op2); 2889 fflush(NULL); 2890 BUG(); 2891 return 2; 2892 } 2893 2894 static struct decoder_info { 2895 struct { 2896 uint32_t bits; 2897 uint32_t mask; 2898 }; 2899 int (*dec)(CPUCRISState *env, DisasContext *dc); 2900 } decinfo[] = { 2901 /* Order matters here. */ 2902 {DEC_MOVEQ, dec_moveq}, 2903 {DEC_BTSTQ, dec_btstq}, 2904 {DEC_CMPQ, dec_cmpq}, 2905 {DEC_ADDOQ, dec_addoq}, 2906 {DEC_ADDQ, dec_addq}, 2907 {DEC_SUBQ, dec_subq}, 2908 {DEC_ANDQ, dec_andq}, 2909 {DEC_ORQ, dec_orq}, 2910 {DEC_ASRQ, dec_asrq}, 2911 {DEC_LSLQ, dec_lslq}, 2912 {DEC_LSRQ, dec_lsrq}, 2913 {DEC_BCCQ, dec_bccq}, 2914 2915 {DEC_BCC_IM, dec_bcc_im}, 2916 {DEC_JAS_IM, dec_jas_im}, 2917 {DEC_JAS_R, dec_jas_r}, 2918 {DEC_JASC_IM, dec_jasc_im}, 2919 {DEC_JASC_R, dec_jasc_r}, 2920 {DEC_BAS_IM, dec_bas_im}, 2921 {DEC_BASC_IM, dec_basc_im}, 2922 {DEC_JUMP_P, dec_jump_p}, 2923 {DEC_LAPC_IM, dec_lapc_im}, 2924 {DEC_LAPCQ, dec_lapcq}, 2925 2926 {DEC_RFE_ETC, dec_rfe_etc}, 2927 {DEC_ADDC_MR, dec_addc_mr}, 2928 2929 {DEC_MOVE_MP, dec_move_mp}, 2930 {DEC_MOVE_PM, dec_move_pm}, 2931 {DEC_MOVEM_MR, dec_movem_mr}, 2932 {DEC_MOVEM_RM, dec_movem_rm}, 2933 {DEC_MOVE_PR, dec_move_pr}, 2934 {DEC_SCC_R, dec_scc_r}, 2935 {DEC_SETF, dec_setclrf}, 2936 {DEC_CLEARF, dec_setclrf}, 2937 2938 {DEC_MOVE_SR, dec_move_sr}, 2939 {DEC_MOVE_RP, dec_move_rp}, 2940 {DEC_SWAP_R, dec_swap_r}, 2941 {DEC_ABS_R, dec_abs_r}, 2942 {DEC_LZ_R, dec_lz_r}, 2943 {DEC_MOVE_RS, dec_move_rs}, 2944 {DEC_BTST_R, dec_btst_r}, 2945 {DEC_ADDC_R, dec_addc_r}, 2946 2947 {DEC_DSTEP_R, dec_dstep_r}, 2948 {DEC_XOR_R, dec_xor_r}, 2949 {DEC_MCP_R, dec_mcp_r}, 2950 {DEC_CMP_R, dec_cmp_r}, 2951 2952 {DEC_ADDI_R, dec_addi_r}, 2953 {DEC_ADDI_ACR, dec_addi_acr}, 2954 2955 {DEC_ADD_R, dec_add_r}, 2956 {DEC_SUB_R, dec_sub_r}, 2957 2958 {DEC_ADDU_R, dec_addu_r}, 2959 {DEC_ADDS_R, dec_adds_r}, 2960 {DEC_SUBU_R, dec_subu_r}, 2961 {DEC_SUBS_R, dec_subs_r}, 2962 {DEC_LSL_R, dec_lsl_r}, 2963 2964 {DEC_AND_R, dec_and_r}, 2965 {DEC_OR_R, dec_or_r}, 2966 {DEC_BOUND_R, dec_bound_r}, 2967 {DEC_ASR_R, dec_asr_r}, 2968 {DEC_LSR_R, dec_lsr_r}, 2969 2970 {DEC_MOVU_R, dec_movu_r}, 2971 {DEC_MOVS_R, dec_movs_r}, 2972 {DEC_NEG_R, dec_neg_r}, 2973 {DEC_MOVE_R, dec_move_r}, 2974 2975 {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m}, 2976 {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m}, 2977 2978 {DEC_MULS_R, dec_muls_r}, 2979 {DEC_MULU_R, dec_mulu_r}, 2980 2981 {DEC_ADDU_M, dec_addu_m}, 2982 {DEC_ADDS_M, dec_adds_m}, 2983 {DEC_SUBU_M, dec_subu_m}, 2984 {DEC_SUBS_M, dec_subs_m}, 2985 2986 {DEC_CMPU_M, dec_cmpu_m}, 2987 {DEC_CMPS_M, dec_cmps_m}, 2988 {DEC_MOVU_M, dec_movu_m}, 2989 {DEC_MOVS_M, dec_movs_m}, 2990 2991 {DEC_CMP_M, dec_cmp_m}, 2992 {DEC_ADDO_M, dec_addo_m}, 2993 {DEC_BOUND_M, dec_bound_m}, 2994 {DEC_ADD_M, dec_add_m}, 2995 {DEC_SUB_M, dec_sub_m}, 2996 {DEC_AND_M, dec_and_m}, 2997 {DEC_OR_M, dec_or_m}, 2998 {DEC_MOVE_RM, dec_move_rm}, 2999 {DEC_TEST_M, dec_test_m}, 3000 {DEC_MOVE_MR, dec_move_mr}, 3001 3002 {{0, 0}, dec_null} 3003 }; 3004 3005 static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc) 3006 { 3007 int insn_len = 2; 3008 int i; 3009 3010 /* Load a halfword onto the instruction register. */ 3011 dc->ir = cris_fetch(env, dc, dc->pc, 2, 0); 3012 3013 /* Now decode it. */ 3014 dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11); 3015 dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3); 3016 dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15); 3017 dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4); 3018 dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5); 3019 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10); 3020 3021 /* Large switch for all insns. */ 3022 for (i = 0; i < ARRAY_SIZE(decinfo); i++) { 3023 if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) { 3024 insn_len = decinfo[i].dec(env, dc); 3025 break; 3026 } 3027 } 3028 3029 #if !defined(CONFIG_USER_ONLY) 3030 /* Single-stepping ? */ 3031 if (dc->tb_flags & S_FLAG) { 3032 TCGLabel *l1 = gen_new_label(); 3033 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1); 3034 /* We treat SPC as a break with an odd trap vector. */ 3035 cris_evaluate_flags(dc); 3036 t_gen_mov_env_TN(trap_vector, tcg_const_tl(3)); 3037 tcg_gen_movi_tl(env_pc, dc->pc + insn_len); 3038 tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len); 3039 t_gen_raise_exception(EXCP_BREAK); 3040 gen_set_label(l1); 3041 } 3042 #endif 3043 return insn_len; 3044 } 3045 3046 #include "translate_v10.c" 3047 3048 /* 3049 * Delay slots on QEMU/CRIS. 3050 * 3051 * If an exception hits on a delayslot, the core will let ERP (the Exception 3052 * Return Pointer) point to the branch (the previous) insn and set the lsb to 3053 * to give SW a hint that the exception actually hit on the dslot. 3054 * 3055 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by 3056 * the core and any jmp to an odd addresses will mask off that lsb. It is 3057 * simply there to let sw know there was an exception on a dslot. 3058 * 3059 * When the software returns from an exception, the branch will re-execute. 3060 * On QEMU care needs to be taken when a branch+delayslot sequence is broken 3061 * and the branch and delayslot don't share pages. 3062 * 3063 * The TB contaning the branch insn will set up env->btarget and evaluate 3064 * env->btaken. When the translation loop exits we will note that the branch 3065 * sequence is broken and let env->dslot be the size of the branch insn (those 3066 * vary in length). 3067 * 3068 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb 3069 * set). It will also expect to have env->dslot setup with the size of the 3070 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 3071 * will execute the dslot and take the branch, either to btarget or just one 3072 * insn ahead. 3073 * 3074 * When exceptions occur, we check for env->dslot in do_interrupt to detect 3075 * broken branch sequences and setup $erp accordingly (i.e let it point to the 3076 * branch and set lsb). Then env->dslot gets cleared so that the exception 3077 * handler can enter. When returning from exceptions (jump $erp) the lsb gets 3078 * masked off and we will reexecute the branch insn. 3079 * 3080 */ 3081 3082 /* generate intermediate code for basic block 'tb'. */ 3083 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb) 3084 { 3085 CPUCRISState *env = cs->env_ptr; 3086 uint32_t pc_start; 3087 unsigned int insn_len; 3088 struct DisasContext ctx; 3089 struct DisasContext *dc = &ctx; 3090 uint32_t next_page_start; 3091 target_ulong npc; 3092 int num_insns; 3093 int max_insns; 3094 3095 if (env->pregs[PR_VR] == 32) { 3096 dc->decoder = crisv32_decoder; 3097 dc->clear_locked_irq = 0; 3098 } else { 3099 dc->decoder = crisv10_decoder; 3100 dc->clear_locked_irq = 1; 3101 } 3102 3103 /* Odd PC indicates that branch is rexecuting due to exception in the 3104 * delayslot, like in real hw. 3105 */ 3106 pc_start = tb->pc & ~1; 3107 dc->cpu = cris_env_get_cpu(env); 3108 dc->tb = tb; 3109 3110 dc->is_jmp = DISAS_NEXT; 3111 dc->ppc = pc_start; 3112 dc->pc = pc_start; 3113 dc->singlestep_enabled = cs->singlestep_enabled; 3114 dc->flags_uptodate = 1; 3115 dc->flagx_known = 1; 3116 dc->flags_x = tb->flags & X_FLAG; 3117 dc->cc_x_uptodate = 0; 3118 dc->cc_mask = 0; 3119 dc->update_cc = 0; 3120 dc->clear_prefix = 0; 3121 3122 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 3123 dc->cc_size_uptodate = -1; 3124 3125 /* Decode TB flags. */ 3126 dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \ 3127 | X_FLAG | PFIX_FLAG); 3128 dc->delayed_branch = !!(tb->flags & 7); 3129 if (dc->delayed_branch) { 3130 dc->jmp = JMP_INDIRECT; 3131 } else { 3132 dc->jmp = JMP_NOJMP; 3133 } 3134 3135 dc->cpustate_changed = 0; 3136 3137 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 3138 num_insns = 0; 3139 max_insns = tb->cflags & CF_COUNT_MASK; 3140 if (max_insns == 0) { 3141 max_insns = CF_COUNT_MASK; 3142 } 3143 if (max_insns > TCG_MAX_INSNS) { 3144 max_insns = TCG_MAX_INSNS; 3145 } 3146 3147 gen_tb_start(tb); 3148 do { 3149 tcg_gen_insn_start(dc->delayed_branch == 1 3150 ? dc->ppc | 1 : dc->pc); 3151 num_insns++; 3152 3153 if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { 3154 cris_evaluate_flags(dc); 3155 tcg_gen_movi_tl(env_pc, dc->pc); 3156 t_gen_raise_exception(EXCP_DEBUG); 3157 dc->is_jmp = DISAS_UPDATE; 3158 /* The address covered by the breakpoint must be included in 3159 [tb->pc, tb->pc + tb->size) in order to for it to be 3160 properly cleared -- thus we increment the PC here so that 3161 the logic setting tb->size below does the right thing. */ 3162 dc->pc += 2; 3163 break; 3164 } 3165 3166 /* Pretty disas. */ 3167 LOG_DIS("%8.8x:\t", dc->pc); 3168 3169 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { 3170 gen_io_start(); 3171 } 3172 dc->clear_x = 1; 3173 3174 insn_len = dc->decoder(env, dc); 3175 dc->ppc = dc->pc; 3176 dc->pc += insn_len; 3177 if (dc->clear_x) { 3178 cris_clear_x_flag(dc); 3179 } 3180 3181 /* Check for delayed branches here. If we do it before 3182 actually generating any host code, the simulator will just 3183 loop doing nothing for on this program location. */ 3184 if (dc->delayed_branch) { 3185 dc->delayed_branch--; 3186 if (dc->delayed_branch == 0) { 3187 if (tb->flags & 7) { 3188 t_gen_mov_env_TN(dslot, tcg_const_tl(0)); 3189 } 3190 if (dc->cpustate_changed || !dc->flagx_known 3191 || (dc->flags_x != (tb->flags & X_FLAG))) { 3192 cris_store_direct_jmp(dc); 3193 } 3194 3195 if (dc->clear_locked_irq) { 3196 dc->clear_locked_irq = 0; 3197 t_gen_mov_env_TN(locked_irq, tcg_const_tl(0)); 3198 } 3199 3200 if (dc->jmp == JMP_DIRECT_CC) { 3201 TCGLabel *l1 = gen_new_label(); 3202 cris_evaluate_flags(dc); 3203 3204 /* Conditional jmp. */ 3205 tcg_gen_brcondi_tl(TCG_COND_EQ, 3206 env_btaken, 0, l1); 3207 gen_goto_tb(dc, 1, dc->jmp_pc); 3208 gen_set_label(l1); 3209 gen_goto_tb(dc, 0, dc->pc); 3210 dc->is_jmp = DISAS_TB_JUMP; 3211 dc->jmp = JMP_NOJMP; 3212 } else if (dc->jmp == JMP_DIRECT) { 3213 cris_evaluate_flags(dc); 3214 gen_goto_tb(dc, 0, dc->jmp_pc); 3215 dc->is_jmp = DISAS_TB_JUMP; 3216 dc->jmp = JMP_NOJMP; 3217 } else { 3218 t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc)); 3219 dc->is_jmp = DISAS_JUMP; 3220 } 3221 break; 3222 } 3223 } 3224 3225 /* If we are rexecuting a branch due to exceptions on 3226 delay slots don't break. */ 3227 if (!(tb->pc & 1) && cs->singlestep_enabled) { 3228 break; 3229 } 3230 } while (!dc->is_jmp && !dc->cpustate_changed 3231 && !tcg_op_buf_full() 3232 && !singlestep 3233 && (dc->pc < next_page_start) 3234 && num_insns < max_insns); 3235 3236 if (dc->clear_locked_irq) { 3237 t_gen_mov_env_TN(locked_irq, tcg_const_tl(0)); 3238 } 3239 3240 npc = dc->pc; 3241 3242 if (tb->cflags & CF_LAST_IO) 3243 gen_io_end(); 3244 /* Force an update if the per-tb cpu state has changed. */ 3245 if (dc->is_jmp == DISAS_NEXT 3246 && (dc->cpustate_changed || !dc->flagx_known 3247 || (dc->flags_x != (tb->flags & X_FLAG)))) { 3248 dc->is_jmp = DISAS_UPDATE; 3249 tcg_gen_movi_tl(env_pc, npc); 3250 } 3251 /* Broken branch+delayslot sequence. */ 3252 if (dc->delayed_branch == 1) { 3253 /* Set env->dslot to the size of the branch insn. */ 3254 t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc)); 3255 cris_store_direct_jmp(dc); 3256 } 3257 3258 cris_evaluate_flags(dc); 3259 3260 if (unlikely(cs->singlestep_enabled)) { 3261 if (dc->is_jmp == DISAS_NEXT) { 3262 tcg_gen_movi_tl(env_pc, npc); 3263 } 3264 t_gen_raise_exception(EXCP_DEBUG); 3265 } else { 3266 switch (dc->is_jmp) { 3267 case DISAS_NEXT: 3268 gen_goto_tb(dc, 1, npc); 3269 break; 3270 default: 3271 case DISAS_JUMP: 3272 case DISAS_UPDATE: 3273 /* indicate that the hash table must be used 3274 to find the next TB */ 3275 tcg_gen_exit_tb(0); 3276 break; 3277 case DISAS_SWI: 3278 case DISAS_TB_JUMP: 3279 /* nothing more to generate */ 3280 break; 3281 } 3282 } 3283 gen_tb_end(tb, num_insns); 3284 3285 tb->size = dc->pc - pc_start; 3286 tb->icount = num_insns; 3287 3288 #ifdef DEBUG_DISAS 3289 #if !DISAS_CRIS 3290 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) 3291 && qemu_log_in_addr_range(pc_start)) { 3292 qemu_log_lock(); 3293 qemu_log("--------------\n"); 3294 qemu_log("IN: %s\n", lookup_symbol(pc_start)); 3295 log_target_disas(cs, pc_start, dc->pc - pc_start, 3296 env->pregs[PR_VR]); 3297 qemu_log("\nisize=%d osize=%d\n", 3298 dc->pc - pc_start, tcg_op_buf_count()); 3299 qemu_log_unlock(); 3300 } 3301 #endif 3302 #endif 3303 } 3304 3305 void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, 3306 int flags) 3307 { 3308 CRISCPU *cpu = CRIS_CPU(cs); 3309 CPUCRISState *env = &cpu->env; 3310 const char **regnames; 3311 const char **pregnames; 3312 int i; 3313 3314 if (!env || !f) { 3315 return; 3316 } 3317 if (env->pregs[PR_VR] < 32) { 3318 pregnames = pregnames_v10; 3319 regnames = regnames_v10; 3320 } else { 3321 pregnames = pregnames_v32; 3322 regnames = regnames_v32; 3323 } 3324 3325 cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n" 3326 "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n", 3327 env->pc, env->pregs[PR_CCS], env->btaken, env->btarget, 3328 env->cc_op, 3329 env->cc_src, env->cc_dest, env->cc_result, env->cc_mask); 3330 3331 3332 for (i = 0; i < 16; i++) { 3333 cpu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]); 3334 if ((i + 1) % 4 == 0) { 3335 cpu_fprintf(f, "\n"); 3336 } 3337 } 3338 cpu_fprintf(f, "\nspecial regs:\n"); 3339 for (i = 0; i < 16; i++) { 3340 cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]); 3341 if ((i + 1) % 4 == 0) { 3342 cpu_fprintf(f, "\n"); 3343 } 3344 } 3345 if (env->pregs[PR_VR] >= 32) { 3346 uint32_t srs = env->pregs[PR_SRS]; 3347 cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs); 3348 if (srs < ARRAY_SIZE(env->sregs)) { 3349 for (i = 0; i < 16; i++) { 3350 cpu_fprintf(f, "s%2.2d=%8.8x ", 3351 i, env->sregs[srs][i]); 3352 if ((i + 1) % 4 == 0) { 3353 cpu_fprintf(f, "\n"); 3354 } 3355 } 3356 } 3357 } 3358 cpu_fprintf(f, "\n\n"); 3359 3360 } 3361 3362 void cris_initialize_tcg(void) 3363 { 3364 int i; 3365 3366 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); 3367 tcg_ctx.tcg_env = cpu_env; 3368 cc_x = tcg_global_mem_new(cpu_env, 3369 offsetof(CPUCRISState, cc_x), "cc_x"); 3370 cc_src = tcg_global_mem_new(cpu_env, 3371 offsetof(CPUCRISState, cc_src), "cc_src"); 3372 cc_dest = tcg_global_mem_new(cpu_env, 3373 offsetof(CPUCRISState, cc_dest), 3374 "cc_dest"); 3375 cc_result = tcg_global_mem_new(cpu_env, 3376 offsetof(CPUCRISState, cc_result), 3377 "cc_result"); 3378 cc_op = tcg_global_mem_new(cpu_env, 3379 offsetof(CPUCRISState, cc_op), "cc_op"); 3380 cc_size = tcg_global_mem_new(cpu_env, 3381 offsetof(CPUCRISState, cc_size), 3382 "cc_size"); 3383 cc_mask = tcg_global_mem_new(cpu_env, 3384 offsetof(CPUCRISState, cc_mask), 3385 "cc_mask"); 3386 3387 env_pc = tcg_global_mem_new(cpu_env, 3388 offsetof(CPUCRISState, pc), 3389 "pc"); 3390 env_btarget = tcg_global_mem_new(cpu_env, 3391 offsetof(CPUCRISState, btarget), 3392 "btarget"); 3393 env_btaken = tcg_global_mem_new(cpu_env, 3394 offsetof(CPUCRISState, btaken), 3395 "btaken"); 3396 for (i = 0; i < 16; i++) { 3397 cpu_R[i] = tcg_global_mem_new(cpu_env, 3398 offsetof(CPUCRISState, regs[i]), 3399 regnames_v32[i]); 3400 } 3401 for (i = 0; i < 16; i++) { 3402 cpu_PR[i] = tcg_global_mem_new(cpu_env, 3403 offsetof(CPUCRISState, pregs[i]), 3404 pregnames_v32[i]); 3405 } 3406 } 3407 3408 void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, 3409 target_ulong *data) 3410 { 3411 env->pc = data[0]; 3412 } 3413