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