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