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