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