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