1/* 2 * CRISv10 emulation for qemu: main translation routines. 3 * 4 * Copyright (c) 2010 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#include "qemu/osdep.h" 22#include "crisv10-decode.h" 23 24static const char * const regnames_v10[] = 25{ 26 "$r0", "$r1", "$r2", "$r3", 27 "$r4", "$r5", "$r6", "$r7", 28 "$r8", "$r9", "$r10", "$r11", 29 "$r12", "$r13", "$sp", "$pc", 30}; 31 32static const char * const pregnames_v10[] = 33{ 34 "$bz", "$vr", "$p2", "$p3", 35 "$wz", "$ccr", "$p6-prefix", "$mof", 36 "$dz", "$ibr", "$irp", "$srp", 37 "$bar", "$dccr", "$brp", "$usp", 38}; 39 40/* We need this table to handle preg-moves with implicit width. */ 41static const int preg_sizes_v10[] = { 42 1, /* bz. */ 43 1, /* vr. */ 44 1, /* pid. */ 45 1, /* srs. */ 46 2, /* wz. */ 47 2, 2, 4, 48 4, 4, 4, 4, 49 4, 4, 4, 4, 50}; 51 52static inline int dec10_size(unsigned int size) 53{ 54 size++; 55 if (size == 3) 56 size++; 57 return size; 58} 59 60static inline void cris_illegal_insn(DisasContext *dc) 61{ 62 qemu_log_mask(LOG_GUEST_ERROR, "illegal insn at pc=%x\n", dc->pc); 63 t_gen_raise_exception(EXCP_BREAK); 64 dc->base.is_jmp = DISAS_NORETURN; 65} 66 67static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val, 68 unsigned int size, int mem_index) 69{ 70 TCGLabel *l1 = gen_new_label(); 71 TCGv taddr = tcg_temp_local_new(); 72 TCGv tval = tcg_temp_local_new(); 73 TCGv t1 = tcg_temp_local_new(); 74 dc->postinc = 0; 75 cris_evaluate_flags(dc); 76 77 tcg_gen_mov_tl(taddr, addr); 78 tcg_gen_mov_tl(tval, val); 79 80 /* Store only if F flag isn't set */ 81 tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10); 82 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 83 if (size == 1) { 84 tcg_gen_qemu_st8(tval, taddr, mem_index); 85 } else if (size == 2) { 86 tcg_gen_qemu_st16(tval, taddr, mem_index); 87 } else { 88 tcg_gen_qemu_st32(tval, taddr, mem_index); 89 } 90 gen_set_label(l1); 91 tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */ 92 tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/ 93 tcg_temp_free(t1); 94 tcg_temp_free(tval); 95 tcg_temp_free(taddr); 96} 97 98static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val, 99 unsigned int size) 100{ 101 int mem_index = cpu_mmu_index(&dc->cpu->env, false); 102 103 /* If we get a fault on a delayslot we must keep the jmp state in 104 the cpu-state to be able to re-execute the jmp. */ 105 if (dc->delayed_branch == 1) { 106 cris_store_direct_jmp(dc); 107 } 108 109 /* Conditional writes. */ 110 if (dc->flags_x) { 111 gen_store_v10_conditional(dc, addr, val, size, mem_index); 112 return; 113 } 114 115 if (size == 1) { 116 tcg_gen_qemu_st8(val, addr, mem_index); 117 } else if (size == 2) { 118 tcg_gen_qemu_st16(val, addr, mem_index); 119 } else { 120 tcg_gen_qemu_st32(val, addr, mem_index); 121 } 122} 123 124 125/* Prefix flag and register are used to handle the more complex 126 addressing modes. */ 127static void cris_set_prefix(DisasContext *dc) 128{ 129 dc->clear_prefix = 0; 130 dc->tb_flags |= PFIX_FLAG; 131 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], PFIX_FLAG); 132 133 /* prefix insns don't clear the x flag. */ 134 dc->clear_x = 0; 135 cris_lock_irq(dc); 136} 137 138static void crisv10_prepare_memaddr(DisasContext *dc, 139 TCGv addr, unsigned int size) 140{ 141 if (dc->tb_flags & PFIX_FLAG) { 142 tcg_gen_mov_tl(addr, cpu_PR[PR_PREFIX]); 143 } else { 144 tcg_gen_mov_tl(addr, cpu_R[dc->src]); 145 } 146} 147 148static unsigned int crisv10_post_memaddr(DisasContext *dc, unsigned int size) 149{ 150 unsigned int insn_len = 0; 151 152 if (dc->tb_flags & PFIX_FLAG) { 153 if (dc->mode == CRISV10_MODE_AUTOINC) { 154 tcg_gen_mov_tl(cpu_R[dc->src], cpu_PR[PR_PREFIX]); 155 } 156 } else { 157 if (dc->mode == CRISV10_MODE_AUTOINC) { 158 if (dc->src == 15) { 159 insn_len += size & ~1; 160 } else { 161 tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], size); 162 } 163 } 164 } 165 return insn_len; 166} 167 168static int dec10_prep_move_m(CPUCRISState *env, DisasContext *dc, 169 int s_ext, int memsize, TCGv dst) 170{ 171 unsigned int rs; 172 uint32_t imm; 173 int is_imm; 174 int insn_len = 0; 175 176 rs = dc->src; 177 is_imm = rs == 15 && !(dc->tb_flags & PFIX_FLAG); 178 LOG_DIS("rs=%d rd=%d is_imm=%d mode=%d pfix=%d\n", 179 rs, dc->dst, is_imm, dc->mode, dc->tb_flags & PFIX_FLAG); 180 181 /* Load [$rs] onto T1. */ 182 if (is_imm) { 183 if (memsize != 4) { 184 if (s_ext) { 185 if (memsize == 1) 186 imm = cpu_ldsb_code(env, dc->pc + 2); 187 else 188 imm = cpu_ldsw_code(env, dc->pc + 2); 189 } else { 190 if (memsize == 1) 191 imm = cpu_ldub_code(env, dc->pc + 2); 192 else 193 imm = cpu_lduw_code(env, dc->pc + 2); 194 } 195 } else 196 imm = cpu_ldl_code(env, dc->pc + 2); 197 198 tcg_gen_movi_tl(dst, imm); 199 200 if (dc->mode == CRISV10_MODE_AUTOINC) { 201 insn_len += memsize; 202 if (memsize == 1) 203 insn_len++; 204 tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len); 205 } 206 } else { 207 TCGv addr; 208 209 addr = tcg_temp_new(); 210 cris_flush_cc_state(dc); 211 crisv10_prepare_memaddr(dc, addr, memsize); 212 gen_load(dc, dst, addr, memsize, 0); 213 if (s_ext) 214 t_gen_sext(dst, dst, memsize); 215 else 216 t_gen_zext(dst, dst, memsize); 217 insn_len += crisv10_post_memaddr(dc, memsize); 218 tcg_temp_free(addr); 219 } 220 221 if (dc->mode == CRISV10_MODE_INDIRECT && (dc->tb_flags & PFIX_FLAG)) { 222 dc->dst = dc->src; 223 } 224 return insn_len; 225} 226 227static unsigned int dec10_quick_imm(DisasContext *dc) 228{ 229 int32_t imm, simm; 230 int op; 231 TCGv c; 232 233 /* sign extend. */ 234 imm = dc->ir & ((1 << 6) - 1); 235 simm = (int8_t) (imm << 2); 236 simm >>= 2; 237 switch (dc->opcode) { 238 case CRISV10_QIMM_BDAP_R0: 239 case CRISV10_QIMM_BDAP_R1: 240 case CRISV10_QIMM_BDAP_R2: 241 case CRISV10_QIMM_BDAP_R3: 242 simm = (int8_t)dc->ir; 243 LOG_DIS("bdap %d $r%d\n", simm, dc->dst); 244 LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n", 245 dc->pc, dc->mode, dc->opcode, dc->src, dc->dst); 246 cris_set_prefix(dc); 247 if (dc->dst == 15) { 248 tcg_gen_movi_tl(cpu_PR[PR_PREFIX], dc->pc + 2 + simm); 249 } else { 250 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm); 251 } 252 break; 253 254 case CRISV10_QIMM_MOVEQ: 255 LOG_DIS("moveq %d, $r%d\n", simm, dc->dst); 256 257 cris_cc_mask(dc, CC_MASK_NZVC); 258 c = tcg_const_tl(simm); 259 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], 260 cpu_R[dc->dst], c, 4); 261 tcg_temp_free(c); 262 break; 263 case CRISV10_QIMM_CMPQ: 264 LOG_DIS("cmpq %d, $r%d\n", simm, dc->dst); 265 266 cris_cc_mask(dc, CC_MASK_NZVC); 267 c = tcg_const_tl(simm); 268 cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst], 269 cpu_R[dc->dst], c, 4); 270 tcg_temp_free(c); 271 break; 272 case CRISV10_QIMM_ADDQ: 273 LOG_DIS("addq %d, $r%d\n", imm, dc->dst); 274 275 cris_cc_mask(dc, CC_MASK_NZVC); 276 c = tcg_const_tl(imm); 277 cris_alu(dc, CC_OP_ADD, cpu_R[dc->dst], 278 cpu_R[dc->dst], c, 4); 279 tcg_temp_free(c); 280 break; 281 case CRISV10_QIMM_ANDQ: 282 LOG_DIS("andq %d, $r%d\n", simm, dc->dst); 283 284 cris_cc_mask(dc, CC_MASK_NZVC); 285 c = tcg_const_tl(simm); 286 cris_alu(dc, CC_OP_AND, cpu_R[dc->dst], 287 cpu_R[dc->dst], c, 4); 288 tcg_temp_free(c); 289 break; 290 case CRISV10_QIMM_ASHQ: 291 LOG_DIS("ashq %d, $r%d\n", simm, dc->dst); 292 293 cris_cc_mask(dc, CC_MASK_NZVC); 294 op = imm & (1 << 5); 295 imm &= 0x1f; 296 c = tcg_const_tl(imm); 297 if (op) { 298 cris_alu(dc, CC_OP_ASR, cpu_R[dc->dst], 299 cpu_R[dc->dst], c, 4); 300 } else { 301 /* BTST */ 302 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 303 gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst], 304 c, cpu_PR[PR_CCS]); 305 } 306 tcg_temp_free(c); 307 break; 308 case CRISV10_QIMM_LSHQ: 309 LOG_DIS("lshq %d, $r%d\n", simm, dc->dst); 310 311 op = CC_OP_LSL; 312 if (imm & (1 << 5)) { 313 op = CC_OP_LSR; 314 } 315 imm &= 0x1f; 316 cris_cc_mask(dc, CC_MASK_NZVC); 317 c = tcg_const_tl(imm); 318 cris_alu(dc, op, cpu_R[dc->dst], 319 cpu_R[dc->dst], c, 4); 320 tcg_temp_free(c); 321 break; 322 case CRISV10_QIMM_SUBQ: 323 LOG_DIS("subq %d, $r%d\n", imm, dc->dst); 324 325 cris_cc_mask(dc, CC_MASK_NZVC); 326 c = tcg_const_tl(imm); 327 cris_alu(dc, CC_OP_SUB, cpu_R[dc->dst], 328 cpu_R[dc->dst], c, 4); 329 tcg_temp_free(c); 330 break; 331 case CRISV10_QIMM_ORQ: 332 LOG_DIS("andq %d, $r%d\n", simm, dc->dst); 333 334 cris_cc_mask(dc, CC_MASK_NZVC); 335 c = tcg_const_tl(simm); 336 cris_alu(dc, CC_OP_OR, cpu_R[dc->dst], 337 cpu_R[dc->dst], c, 4); 338 tcg_temp_free(c); 339 break; 340 341 case CRISV10_QIMM_BCC_R0: 342 case CRISV10_QIMM_BCC_R1: 343 case CRISV10_QIMM_BCC_R2: 344 case CRISV10_QIMM_BCC_R3: 345 imm = dc->ir & 0xff; 346 /* bit 0 is a sign bit. */ 347 if (imm & 1) { 348 imm |= 0xffffff00; /* sign extend. */ 349 imm &= ~1; /* get rid of the sign bit. */ 350 } 351 imm += 2; 352 LOG_DIS("b%s %d\n", cc_name(dc->cond), imm); 353 354 cris_cc_mask(dc, 0); 355 cris_prepare_cc_branch(dc, imm, dc->cond); 356 break; 357 358 default: 359 LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n", 360 dc->pc, dc->mode, dc->opcode, dc->src, dc->dst); 361 cpu_abort(CPU(dc->cpu), "Unhandled quickimm\n"); 362 break; 363 } 364 return 2; 365} 366 367static unsigned int dec10_setclrf(DisasContext *dc) 368{ 369 uint32_t flags; 370 unsigned int set = ~dc->opcode & 1; 371 372 flags = EXTRACT_FIELD(dc->ir, 0, 3) 373 | (EXTRACT_FIELD(dc->ir, 12, 15) << 4); 374 LOG_DIS("%s set=%d flags=%x\n", __func__, set, flags); 375 376 377 if (flags & X_FLAG) { 378 if (set) 379 dc->flags_x = X_FLAG; 380 else 381 dc->flags_x = 0; 382 } 383 384 cris_evaluate_flags (dc); 385 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 386 cris_update_cc_x(dc); 387 tcg_gen_movi_tl(cc_op, dc->cc_op); 388 389 if (set) { 390 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags); 391 } else { 392 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], 393 ~(flags|F_FLAG_V10|P_FLAG_V10)); 394 } 395 396 dc->flags_uptodate = 1; 397 dc->clear_x = 0; 398 cris_lock_irq(dc); 399 return 2; 400} 401 402static inline void dec10_reg_prep_sext(DisasContext *dc, int size, int sext, 403 TCGv dd, TCGv ds, TCGv sd, TCGv ss) 404{ 405 if (sext) { 406 t_gen_sext(dd, sd, size); 407 t_gen_sext(ds, ss, size); 408 } else { 409 t_gen_zext(dd, sd, size); 410 t_gen_zext(ds, ss, size); 411 } 412} 413 414static void dec10_reg_alu(DisasContext *dc, int op, int size, int sext) 415{ 416 TCGv t[2]; 417 418 t[0] = tcg_temp_new(); 419 t[1] = tcg_temp_new(); 420 dec10_reg_prep_sext(dc, size, sext, 421 t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]); 422 423 if (op == CC_OP_LSL || op == CC_OP_LSR || op == CC_OP_ASR) { 424 tcg_gen_andi_tl(t[1], t[1], 63); 425 } 426 427 assert(dc->dst != 15); 428 cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], size); 429 tcg_temp_free(t[0]); 430 tcg_temp_free(t[1]); 431} 432 433static void dec10_reg_bound(DisasContext *dc, int size) 434{ 435 TCGv t; 436 437 t = tcg_temp_local_new(); 438 t_gen_zext(t, cpu_R[dc->src], size); 439 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4); 440 tcg_temp_free(t); 441} 442 443static void dec10_reg_mul(DisasContext *dc, int size, int sext) 444{ 445 int op = sext ? CC_OP_MULS : CC_OP_MULU; 446 TCGv t[2]; 447 448 t[0] = tcg_temp_new(); 449 t[1] = tcg_temp_new(); 450 dec10_reg_prep_sext(dc, size, sext, 451 t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]); 452 453 cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], 4); 454 455 tcg_temp_free(t[0]); 456 tcg_temp_free(t[1]); 457} 458 459 460static void dec10_reg_movs(DisasContext *dc) 461{ 462 int size = (dc->size & 1) + 1; 463 TCGv t; 464 465 LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst); 466 cris_cc_mask(dc, CC_MASK_NZVC); 467 468 t = tcg_temp_new(); 469 if (dc->ir & 32) 470 t_gen_sext(t, cpu_R[dc->src], size); 471 else 472 t_gen_zext(t, cpu_R[dc->src], size); 473 474 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, 4); 475 tcg_temp_free(t); 476} 477 478static void dec10_reg_alux(DisasContext *dc, int op) 479{ 480 int size = (dc->size & 1) + 1; 481 TCGv t; 482 483 LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst); 484 cris_cc_mask(dc, CC_MASK_NZVC); 485 486 t = tcg_temp_new(); 487 if (dc->ir & 32) 488 t_gen_sext(t, cpu_R[dc->src], size); 489 else 490 t_gen_zext(t, cpu_R[dc->src], size); 491 492 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[dc->dst], t, 4); 493 tcg_temp_free(t); 494} 495 496static void dec10_reg_mov_pr(DisasContext *dc) 497{ 498 LOG_DIS("move p%d r%d sz=%d\n", dc->dst, dc->src, preg_sizes_v10[dc->dst]); 499 cris_lock_irq(dc); 500 if (dc->src == 15) { 501 tcg_gen_mov_tl(env_btarget, cpu_PR[dc->dst]); 502 cris_prepare_jmp(dc, JMP_INDIRECT); 503 return; 504 } 505 if (dc->dst == PR_CCS) { 506 cris_evaluate_flags(dc); 507 } 508 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], 509 cpu_R[dc->src], cpu_PR[dc->dst], preg_sizes_v10[dc->dst]); 510} 511 512static void dec10_reg_abs(DisasContext *dc) 513{ 514 TCGv t0; 515 516 LOG_DIS("abs $r%u, $r%u\n", dc->src, dc->dst); 517 518 assert(dc->dst != 15); 519 t0 = tcg_temp_new(); 520 tcg_gen_sari_tl(t0, cpu_R[dc->src], 31); 521 tcg_gen_xor_tl(cpu_R[dc->dst], cpu_R[dc->src], t0); 522 tcg_gen_sub_tl(t0, cpu_R[dc->dst], t0); 523 524 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t0, 4); 525 tcg_temp_free(t0); 526} 527 528static void dec10_reg_swap(DisasContext *dc) 529{ 530 TCGv t0; 531 532 LOG_DIS("not $r%d, $r%d\n", dc->src, dc->dst); 533 534 cris_cc_mask(dc, CC_MASK_NZVC); 535 t0 = tcg_temp_new(); 536 tcg_gen_mov_tl(t0, cpu_R[dc->src]); 537 if (dc->dst & 8) 538 tcg_gen_not_tl(t0, t0); 539 if (dc->dst & 4) 540 t_gen_swapw(t0, t0); 541 if (dc->dst & 2) 542 t_gen_swapb(t0, t0); 543 if (dc->dst & 1) 544 t_gen_swapr(t0, t0); 545 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], cpu_R[dc->src], t0, 4); 546 tcg_temp_free(t0); 547} 548 549static void dec10_reg_scc(DisasContext *dc) 550{ 551 int cond = dc->dst; 552 553 LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src); 554 555 gen_tst_cc(dc, cpu_R[dc->src], cond); 556 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->src], cpu_R[dc->src], 0); 557 558 cris_cc_mask(dc, 0); 559} 560 561static unsigned int dec10_reg(DisasContext *dc) 562{ 563 TCGv t; 564 unsigned int insn_len = 2; 565 unsigned int size = dec10_size(dc->size); 566 unsigned int tmp; 567 568 if (dc->size != 3) { 569 switch (dc->opcode) { 570 case CRISV10_REG_MOVE_R: 571 LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst); 572 cris_cc_mask(dc, CC_MASK_NZVC); 573 dec10_reg_alu(dc, CC_OP_MOVE, size, 0); 574 if (dc->dst == 15) { 575 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 576 cris_prepare_jmp(dc, JMP_INDIRECT); 577 dc->delayed_branch = 1; 578 } 579 break; 580 case CRISV10_REG_MOVX: 581 cris_cc_mask(dc, CC_MASK_NZVC); 582 dec10_reg_movs(dc); 583 break; 584 case CRISV10_REG_ADDX: 585 cris_cc_mask(dc, CC_MASK_NZVC); 586 dec10_reg_alux(dc, CC_OP_ADD); 587 break; 588 case CRISV10_REG_SUBX: 589 cris_cc_mask(dc, CC_MASK_NZVC); 590 dec10_reg_alux(dc, CC_OP_SUB); 591 break; 592 case CRISV10_REG_ADD: 593 LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 594 cris_cc_mask(dc, CC_MASK_NZVC); 595 dec10_reg_alu(dc, CC_OP_ADD, size, 0); 596 break; 597 case CRISV10_REG_SUB: 598 LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 599 cris_cc_mask(dc, CC_MASK_NZVC); 600 dec10_reg_alu(dc, CC_OP_SUB, size, 0); 601 break; 602 case CRISV10_REG_CMP: 603 LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 604 cris_cc_mask(dc, CC_MASK_NZVC); 605 dec10_reg_alu(dc, CC_OP_CMP, size, 0); 606 break; 607 case CRISV10_REG_BOUND: 608 LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 609 cris_cc_mask(dc, CC_MASK_NZVC); 610 dec10_reg_bound(dc, size); 611 break; 612 case CRISV10_REG_AND: 613 LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 614 cris_cc_mask(dc, CC_MASK_NZVC); 615 dec10_reg_alu(dc, CC_OP_AND, size, 0); 616 break; 617 case CRISV10_REG_ADDI: 618 if (dc->src == 15) { 619 /* nop. */ 620 return 2; 621 } 622 t = tcg_temp_new(); 623 LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size); 624 tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3); 625 tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t); 626 tcg_temp_free(t); 627 break; 628 case CRISV10_REG_LSL: 629 LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 630 cris_cc_mask(dc, CC_MASK_NZVC); 631 dec10_reg_alu(dc, CC_OP_LSL, size, 0); 632 break; 633 case CRISV10_REG_LSR: 634 LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 635 cris_cc_mask(dc, CC_MASK_NZVC); 636 dec10_reg_alu(dc, CC_OP_LSR, size, 0); 637 break; 638 case CRISV10_REG_ASR: 639 LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 640 cris_cc_mask(dc, CC_MASK_NZVC); 641 dec10_reg_alu(dc, CC_OP_ASR, size, 1); 642 break; 643 case CRISV10_REG_OR: 644 LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 645 cris_cc_mask(dc, CC_MASK_NZVC); 646 dec10_reg_alu(dc, CC_OP_OR, size, 0); 647 break; 648 case CRISV10_REG_NEG: 649 LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 650 cris_cc_mask(dc, CC_MASK_NZVC); 651 dec10_reg_alu(dc, CC_OP_NEG, size, 0); 652 break; 653 case CRISV10_REG_BIAP: 654 LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc, 655 dc->opcode, dc->src, dc->dst, size); 656 switch (size) { 657 case 4: tmp = 2; break; 658 case 2: tmp = 1; break; 659 case 1: tmp = 0; break; 660 default: 661 cpu_abort(CPU(dc->cpu), "Unhandled BIAP"); 662 break; 663 } 664 665 t = tcg_temp_new(); 666 tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp); 667 if (dc->src == 15) { 668 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1); 669 } else { 670 tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t); 671 } 672 tcg_temp_free(t); 673 cris_set_prefix(dc); 674 break; 675 676 default: 677 LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc, 678 dc->opcode, dc->src, dc->dst); 679 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 680 break; 681 } 682 } else { 683 switch (dc->opcode) { 684 case CRISV10_REG_MOVX: 685 cris_cc_mask(dc, CC_MASK_NZVC); 686 dec10_reg_movs(dc); 687 break; 688 case CRISV10_REG_ADDX: 689 cris_cc_mask(dc, CC_MASK_NZVC); 690 dec10_reg_alux(dc, CC_OP_ADD); 691 break; 692 case CRISV10_REG_SUBX: 693 cris_cc_mask(dc, CC_MASK_NZVC); 694 dec10_reg_alux(dc, CC_OP_SUB); 695 break; 696 case CRISV10_REG_MOVE_SPR_R: 697 cris_evaluate_flags(dc); 698 cris_cc_mask(dc, 0); 699 dec10_reg_mov_pr(dc); 700 break; 701 case CRISV10_REG_MOVE_R_SPR: 702 LOG_DIS("move r%d p%d\n", dc->src, dc->dst); 703 cris_evaluate_flags(dc); 704 if (dc->src != 11) /* fast for srp. */ 705 dc->cpustate_changed = 1; 706 t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]); 707 break; 708 case CRISV10_REG_SETF: 709 case CRISV10_REG_CLEARF: 710 dec10_setclrf(dc); 711 break; 712 case CRISV10_REG_SWAP: 713 dec10_reg_swap(dc); 714 break; 715 case CRISV10_REG_ABS: 716 cris_cc_mask(dc, CC_MASK_NZVC); 717 dec10_reg_abs(dc); 718 break; 719 case CRISV10_REG_LZ: 720 LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 721 cris_cc_mask(dc, CC_MASK_NZVC); 722 dec10_reg_alu(dc, CC_OP_LZ, 4, 0); 723 break; 724 case CRISV10_REG_XOR: 725 LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 726 cris_cc_mask(dc, CC_MASK_NZVC); 727 dec10_reg_alu(dc, CC_OP_XOR, 4, 0); 728 break; 729 case CRISV10_REG_BTST: 730 LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 731 cris_cc_mask(dc, CC_MASK_NZVC); 732 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 733 gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst], 734 cpu_R[dc->src], cpu_PR[PR_CCS]); 735 break; 736 case CRISV10_REG_DSTEP: 737 LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 738 cris_cc_mask(dc, CC_MASK_NZVC); 739 cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst], 740 cpu_R[dc->dst], cpu_R[dc->src], 4); 741 break; 742 case CRISV10_REG_MSTEP: 743 LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 744 cris_evaluate_flags(dc); 745 cris_cc_mask(dc, CC_MASK_NZVC); 746 cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst], 747 cpu_R[dc->dst], cpu_R[dc->src], 4); 748 break; 749 case CRISV10_REG_SCC: 750 dec10_reg_scc(dc); 751 break; 752 default: 753 LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc, 754 dc->opcode, dc->src, dc->dst); 755 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 756 break; 757 } 758 } 759 return insn_len; 760} 761 762static unsigned int dec10_ind_move_m_r(CPUCRISState *env, DisasContext *dc, 763 unsigned int size) 764{ 765 unsigned int insn_len = 2; 766 TCGv t; 767 768 LOG_DIS("%s: move.%d [$r%d], $r%d\n", __func__, 769 size, dc->src, dc->dst); 770 771 cris_cc_mask(dc, CC_MASK_NZVC); 772 t = tcg_temp_new(); 773 insn_len += dec10_prep_move_m(env, dc, 0, size, t); 774 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size); 775 if (dc->dst == 15) { 776 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 777 cris_prepare_jmp(dc, JMP_INDIRECT); 778 dc->delayed_branch = 1; 779 } 780 781 tcg_temp_free(t); 782 return insn_len; 783} 784 785static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size) 786{ 787 unsigned int insn_len = 2; 788 TCGv addr; 789 790 LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst); 791 addr = tcg_temp_new(); 792 crisv10_prepare_memaddr(dc, addr, size); 793 gen_store_v10(dc, addr, cpu_R[dc->dst], size); 794 insn_len += crisv10_post_memaddr(dc, size); 795 tcg_temp_free(addr); 796 797 return insn_len; 798} 799 800static unsigned int dec10_ind_move_m_pr(CPUCRISState *env, DisasContext *dc) 801{ 802 unsigned int insn_len = 2, rd = dc->dst; 803 TCGv t, addr; 804 805 LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src); 806 cris_lock_irq(dc); 807 808 addr = tcg_temp_new(); 809 t = tcg_temp_new(); 810 insn_len += dec10_prep_move_m(env, dc, 0, 4, t); 811 if (rd == 15) { 812 tcg_gen_mov_tl(env_btarget, t); 813 cris_prepare_jmp(dc, JMP_INDIRECT); 814 dc->delayed_branch = 1; 815 } else { 816 tcg_gen_mov_tl(cpu_PR[rd], t); 817 dc->cpustate_changed = 1; 818 } 819 tcg_temp_free(addr); 820 tcg_temp_free(t); 821 return insn_len; 822} 823 824static unsigned int dec10_ind_move_pr_m(DisasContext *dc) 825{ 826 unsigned int insn_len = 2, size = preg_sizes_v10[dc->dst]; 827 TCGv addr, t0; 828 829 LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src); 830 831 addr = tcg_temp_new(); 832 crisv10_prepare_memaddr(dc, addr, size); 833 if (dc->dst == PR_CCS) { 834 t0 = tcg_temp_new(); 835 cris_evaluate_flags(dc); 836 tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG); 837 gen_store_v10(dc, addr, t0, size); 838 tcg_temp_free(t0); 839 } else { 840 gen_store_v10(dc, addr, cpu_PR[dc->dst], size); 841 } 842 insn_len += crisv10_post_memaddr(dc, size); 843 tcg_temp_free(addr); 844 cris_lock_irq(dc); 845 846 return insn_len; 847} 848 849static void dec10_movem_r_m(DisasContext *dc) 850{ 851 int i, pfix = dc->tb_flags & PFIX_FLAG; 852 TCGv addr, t0; 853 854 LOG_DIS("%s r%d, [r%d] pi=%d ir=%x\n", __func__, 855 dc->dst, dc->src, dc->postinc, dc->ir); 856 857 addr = tcg_temp_new(); 858 t0 = tcg_temp_new(); 859 crisv10_prepare_memaddr(dc, addr, 4); 860 tcg_gen_mov_tl(t0, addr); 861 for (i = dc->dst; i >= 0; i--) { 862 if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) { 863 gen_store_v10(dc, addr, t0, 4); 864 } else { 865 gen_store_v10(dc, addr, cpu_R[i], 4); 866 } 867 tcg_gen_addi_tl(addr, addr, 4); 868 } 869 870 if (pfix && dc->mode == CRISV10_MODE_AUTOINC) { 871 tcg_gen_mov_tl(cpu_R[dc->src], t0); 872 } 873 874 if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) { 875 tcg_gen_mov_tl(cpu_R[dc->src], addr); 876 } 877 tcg_temp_free(addr); 878 tcg_temp_free(t0); 879} 880 881static void dec10_movem_m_r(DisasContext *dc) 882{ 883 int i, pfix = dc->tb_flags & PFIX_FLAG; 884 TCGv addr, t0; 885 886 LOG_DIS("%s [r%d], r%d pi=%d ir=%x\n", __func__, 887 dc->src, dc->dst, dc->postinc, dc->ir); 888 889 addr = tcg_temp_new(); 890 t0 = tcg_temp_new(); 891 crisv10_prepare_memaddr(dc, addr, 4); 892 tcg_gen_mov_tl(t0, addr); 893 for (i = dc->dst; i >= 0; i--) { 894 gen_load(dc, cpu_R[i], addr, 4, 0); 895 tcg_gen_addi_tl(addr, addr, 4); 896 } 897 898 if (pfix && dc->mode == CRISV10_MODE_AUTOINC) { 899 tcg_gen_mov_tl(cpu_R[dc->src], t0); 900 } 901 902 if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) { 903 tcg_gen_mov_tl(cpu_R[dc->src], addr); 904 } 905 tcg_temp_free(addr); 906 tcg_temp_free(t0); 907} 908 909static int dec10_ind_alu(CPUCRISState *env, DisasContext *dc, 910 int op, unsigned int size) 911{ 912 int insn_len = 0; 913 int rd = dc->dst; 914 TCGv t[2]; 915 916 cris_alu_m_alloc_temps(t); 917 insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]); 918 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size); 919 if (dc->dst == 15) { 920 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 921 cris_prepare_jmp(dc, JMP_INDIRECT); 922 dc->delayed_branch = 1; 923 return insn_len; 924 } 925 926 cris_alu_m_free_temps(t); 927 928 return insn_len; 929} 930 931static int dec10_ind_bound(CPUCRISState *env, DisasContext *dc, 932 unsigned int size) 933{ 934 int insn_len = 0; 935 int rd = dc->dst; 936 TCGv t; 937 938 t = tcg_temp_local_new(); 939 insn_len += dec10_prep_move_m(env, dc, 0, size, t); 940 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4); 941 if (dc->dst == 15) { 942 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 943 cris_prepare_jmp(dc, JMP_INDIRECT); 944 dc->delayed_branch = 1; 945 } 946 947 tcg_temp_free(t); 948 return insn_len; 949} 950 951static int dec10_alux_m(CPUCRISState *env, DisasContext *dc, int op) 952{ 953 unsigned int size = (dc->size & 1) ? 2 : 1; 954 unsigned int sx = !!(dc->size & 2); 955 int insn_len = 2; 956 int rd = dc->dst; 957 TCGv t; 958 959 LOG_DIS("addx size=%d sx=%d op=%d %d\n", size, sx, dc->src, dc->dst); 960 961 t = tcg_temp_new(); 962 963 cris_cc_mask(dc, CC_MASK_NZVC); 964 insn_len += dec10_prep_move_m(env, dc, sx, size, t); 965 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4); 966 if (dc->dst == 15) { 967 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 968 cris_prepare_jmp(dc, JMP_INDIRECT); 969 dc->delayed_branch = 1; 970 } 971 972 tcg_temp_free(t); 973 return insn_len; 974} 975 976static int dec10_dip(CPUCRISState *env, DisasContext *dc) 977{ 978 int insn_len = 2; 979 uint32_t imm; 980 981 LOG_DIS("dip pc=%x opcode=%d r%d r%d\n", 982 dc->pc, dc->opcode, dc->src, dc->dst); 983 if (dc->src == 15) { 984 imm = cpu_ldl_code(env, dc->pc + 2); 985 tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm); 986 if (dc->postinc) 987 insn_len += 4; 988 tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len - 2); 989 } else { 990 gen_load(dc, cpu_PR[PR_PREFIX], cpu_R[dc->src], 4, 0); 991 if (dc->postinc) 992 tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], 4); 993 } 994 995 cris_set_prefix(dc); 996 return insn_len; 997} 998 999static int dec10_bdap_m(CPUCRISState *env, DisasContext *dc, int size) 1000{ 1001 int insn_len = 2; 1002 int rd = dc->dst; 1003 1004 LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n", 1005 dc->pc, dc->opcode, dc->src, dc->dst, size); 1006 1007 assert(dc->dst != 15); 1008#if 0 1009 /* 8bit embedded offset? */ 1010 if (!dc->postinc && (dc->ir & (1 << 11))) { 1011 int simm = dc->ir & 0xff; 1012 1013 /* cpu_abort(CPU(dc->cpu), "Unhandled opcode"); */ 1014 /* sign extended. */ 1015 simm = (int8_t)simm; 1016 1017 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm); 1018 1019 cris_set_prefix(dc); 1020 return insn_len; 1021 } 1022#endif 1023 /* Now the rest of the modes are truly indirect. */ 1024 insn_len += dec10_prep_move_m(env, dc, 1, size, cpu_PR[PR_PREFIX]); 1025 tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]); 1026 cris_set_prefix(dc); 1027 return insn_len; 1028} 1029 1030static unsigned int dec10_ind(CPUCRISState *env, DisasContext *dc) 1031{ 1032 unsigned int insn_len = 2; 1033 unsigned int size = dec10_size(dc->size); 1034 uint32_t imm; 1035 int32_t simm; 1036 TCGv t[2], c; 1037 1038 if (dc->size != 3) { 1039 switch (dc->opcode) { 1040 case CRISV10_IND_MOVE_M_R: 1041 return dec10_ind_move_m_r(env, dc, size); 1042 case CRISV10_IND_MOVE_R_M: 1043 return dec10_ind_move_r_m(dc, size); 1044 case CRISV10_IND_CMP: 1045 LOG_DIS("cmp size=%d op=%d %d\n", size, dc->src, dc->dst); 1046 cris_cc_mask(dc, CC_MASK_NZVC); 1047 insn_len += dec10_ind_alu(env, dc, CC_OP_CMP, size); 1048 break; 1049 case CRISV10_IND_TEST: 1050 LOG_DIS("test size=%d op=%d %d\n", size, dc->src, dc->dst); 1051 1052 cris_evaluate_flags(dc); 1053 cris_cc_mask(dc, CC_MASK_NZVC); 1054 cris_alu_m_alloc_temps(t); 1055 insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]); 1056 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3); 1057 c = tcg_const_tl(0); 1058 cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst], 1059 t[0], c, size); 1060 tcg_temp_free(c); 1061 cris_alu_m_free_temps(t); 1062 break; 1063 case CRISV10_IND_ADD: 1064 LOG_DIS("add size=%d op=%d %d\n", size, dc->src, dc->dst); 1065 cris_cc_mask(dc, CC_MASK_NZVC); 1066 insn_len += dec10_ind_alu(env, dc, CC_OP_ADD, size); 1067 break; 1068 case CRISV10_IND_SUB: 1069 LOG_DIS("sub size=%d op=%d %d\n", size, dc->src, dc->dst); 1070 cris_cc_mask(dc, CC_MASK_NZVC); 1071 insn_len += dec10_ind_alu(env, dc, CC_OP_SUB, size); 1072 break; 1073 case CRISV10_IND_BOUND: 1074 LOG_DIS("bound size=%d op=%d %d\n", size, dc->src, dc->dst); 1075 cris_cc_mask(dc, CC_MASK_NZVC); 1076 insn_len += dec10_ind_bound(env, dc, size); 1077 break; 1078 case CRISV10_IND_AND: 1079 LOG_DIS("and size=%d op=%d %d\n", size, dc->src, dc->dst); 1080 cris_cc_mask(dc, CC_MASK_NZVC); 1081 insn_len += dec10_ind_alu(env, dc, CC_OP_AND, size); 1082 break; 1083 case CRISV10_IND_OR: 1084 LOG_DIS("or size=%d op=%d %d\n", size, dc->src, dc->dst); 1085 cris_cc_mask(dc, CC_MASK_NZVC); 1086 insn_len += dec10_ind_alu(env, dc, CC_OP_OR, size); 1087 break; 1088 case CRISV10_IND_MOVX: 1089 insn_len = dec10_alux_m(env, dc, CC_OP_MOVE); 1090 break; 1091 case CRISV10_IND_ADDX: 1092 insn_len = dec10_alux_m(env, dc, CC_OP_ADD); 1093 break; 1094 case CRISV10_IND_SUBX: 1095 insn_len = dec10_alux_m(env, dc, CC_OP_SUB); 1096 break; 1097 case CRISV10_IND_CMPX: 1098 insn_len = dec10_alux_m(env, dc, CC_OP_CMP); 1099 break; 1100 case CRISV10_IND_MUL: 1101 /* This is a reg insn coded in the mem indir space. */ 1102 LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode); 1103 cris_cc_mask(dc, CC_MASK_NZVC); 1104 dec10_reg_mul(dc, size, dc->ir & (1 << 10)); 1105 break; 1106 case CRISV10_IND_BDAP_M: 1107 insn_len = dec10_bdap_m(env, dc, size); 1108 break; 1109 default: 1110 /* 1111 * ADDC for v17: 1112 * 1113 * Instruction format: ADDC [Rs],Rd 1114 * 1115 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1116 * |Destination(Rd)| 1 0 0 1 1 0 1 0 | Source(Rs)| 1117 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+ 1118 * 1119 * Instruction format: ADDC [Rs+],Rd 1120 * 1121 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1122 * |Destination(Rd)| 1 1 0 1 1 0 1 0 | Source(Rs)| 1123 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1124 */ 1125 if (dc->opcode == CRISV17_IND_ADDC && dc->size == 2 && 1126 env->pregs[PR_VR] == 17) { 1127 LOG_DIS("addc op=%d %d\n", dc->src, dc->dst); 1128 cris_cc_mask(dc, CC_MASK_NZVC); 1129 insn_len += dec10_ind_alu(env, dc, CC_OP_ADDC, size); 1130 break; 1131 } 1132 1133 LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n", 1134 dc->pc, size, dc->opcode, dc->src, dc->dst); 1135 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 1136 break; 1137 } 1138 return insn_len; 1139 } 1140 1141 switch (dc->opcode) { 1142 case CRISV10_IND_MOVE_M_SPR: 1143 insn_len = dec10_ind_move_m_pr(env, dc); 1144 break; 1145 case CRISV10_IND_MOVE_SPR_M: 1146 insn_len = dec10_ind_move_pr_m(dc); 1147 break; 1148 case CRISV10_IND_JUMP_M: 1149 if (dc->src == 15) { 1150 LOG_DIS("jump.%d %d r%d r%d direct\n", size, 1151 dc->opcode, dc->src, dc->dst); 1152 imm = cpu_ldl_code(env, dc->pc + 2); 1153 if (dc->mode == CRISV10_MODE_AUTOINC) 1154 insn_len += size; 1155 1156 c = tcg_const_tl(dc->pc + insn_len); 1157 t_gen_mov_preg_TN(dc, dc->dst, c); 1158 tcg_temp_free(c); 1159 dc->jmp_pc = imm; 1160 cris_prepare_jmp(dc, JMP_DIRECT); 1161 dc->delayed_branch--; /* v10 has no dslot here. */ 1162 } else { 1163 if (dc->dst == 14) { 1164 LOG_DIS("break %d\n", dc->src); 1165 cris_evaluate_flags(dc); 1166 tcg_gen_movi_tl(env_pc, dc->pc + 2); 1167 c = tcg_const_tl(dc->src + 2); 1168 t_gen_mov_env_TN(trap_vector, c); 1169 tcg_temp_free(c); 1170 t_gen_raise_exception(EXCP_BREAK); 1171 dc->base.is_jmp = DISAS_NORETURN; 1172 return insn_len; 1173 } 1174 LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size, 1175 dc->opcode, dc->src, dc->dst); 1176 t[0] = tcg_temp_new(); 1177 c = tcg_const_tl(dc->pc + insn_len); 1178 t_gen_mov_preg_TN(dc, dc->dst, c); 1179 tcg_temp_free(c); 1180 crisv10_prepare_memaddr(dc, t[0], size); 1181 gen_load(dc, env_btarget, t[0], 4, 0); 1182 insn_len += crisv10_post_memaddr(dc, size); 1183 cris_prepare_jmp(dc, JMP_INDIRECT); 1184 dc->delayed_branch--; /* v10 has no dslot here. */ 1185 tcg_temp_free(t[0]); 1186 } 1187 break; 1188 1189 case CRISV10_IND_MOVEM_R_M: 1190 LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n", 1191 dc->pc, dc->opcode, dc->dst, dc->src); 1192 dec10_movem_r_m(dc); 1193 break; 1194 case CRISV10_IND_MOVEM_M_R: 1195 LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode); 1196 dec10_movem_m_r(dc); 1197 break; 1198 case CRISV10_IND_JUMP_R: 1199 LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n", 1200 dc->pc, dc->opcode, dc->dst, dc->src); 1201 tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]); 1202 c = tcg_const_tl(dc->pc + insn_len); 1203 t_gen_mov_preg_TN(dc, dc->dst, c); 1204 tcg_temp_free(c); 1205 cris_prepare_jmp(dc, JMP_INDIRECT); 1206 dc->delayed_branch--; /* v10 has no dslot here. */ 1207 break; 1208 case CRISV10_IND_MOVX: 1209 insn_len = dec10_alux_m(env, dc, CC_OP_MOVE); 1210 break; 1211 case CRISV10_IND_ADDX: 1212 insn_len = dec10_alux_m(env, dc, CC_OP_ADD); 1213 break; 1214 case CRISV10_IND_SUBX: 1215 insn_len = dec10_alux_m(env, dc, CC_OP_SUB); 1216 break; 1217 case CRISV10_IND_CMPX: 1218 insn_len = dec10_alux_m(env, dc, CC_OP_CMP); 1219 break; 1220 case CRISV10_IND_DIP: 1221 insn_len = dec10_dip(env, dc); 1222 break; 1223 case CRISV10_IND_BCC_M: 1224 1225 cris_cc_mask(dc, 0); 1226 simm = cpu_ldsw_code(env, dc->pc + 2); 1227 simm += 4; 1228 1229 LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm); 1230 cris_prepare_cc_branch(dc, simm, dc->cond); 1231 insn_len = 4; 1232 break; 1233 default: 1234 LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode); 1235 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 1236 break; 1237 } 1238 1239 return insn_len; 1240} 1241 1242static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc) 1243{ 1244 unsigned int insn_len = 2; 1245 1246 /* Load a halfword onto the instruction register. */ 1247 dc->ir = cpu_lduw_code(env, dc->pc); 1248 1249 /* Now decode it. */ 1250 dc->opcode = EXTRACT_FIELD(dc->ir, 6, 9); 1251 dc->mode = EXTRACT_FIELD(dc->ir, 10, 11); 1252 dc->src = EXTRACT_FIELD(dc->ir, 0, 3); 1253 dc->size = EXTRACT_FIELD(dc->ir, 4, 5); 1254 dc->cond = dc->dst = EXTRACT_FIELD(dc->ir, 12, 15); 1255 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10); 1256 1257 dc->clear_prefix = 1; 1258 1259 /* FIXME: What if this insn insn't 2 in length?? */ 1260 if (dc->src == 15 || dc->dst == 15) 1261 tcg_gen_movi_tl(cpu_R[15], dc->pc + 2); 1262 1263 switch (dc->mode) { 1264 case CRISV10_MODE_QIMMEDIATE: 1265 insn_len = dec10_quick_imm(dc); 1266 break; 1267 case CRISV10_MODE_REG: 1268 insn_len = dec10_reg(dc); 1269 break; 1270 case CRISV10_MODE_AUTOINC: 1271 case CRISV10_MODE_INDIRECT: 1272 insn_len = dec10_ind(env, dc); 1273 break; 1274 } 1275 1276 if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) { 1277 dc->tb_flags &= ~PFIX_FLAG; 1278 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG); 1279 if (dc->tb_flags != dc->base.tb->flags) { 1280 dc->cpustate_changed = 1; 1281 } 1282 } 1283 1284 /* CRISv10 locks out interrupts on dslots. */ 1285 if (dc->delayed_branch == 2) { 1286 cris_lock_irq(dc); 1287 } 1288 return insn_len; 1289} 1290 1291void cris_initialize_crisv10_tcg(void) 1292{ 1293 int i; 1294 1295 cc_x = tcg_global_mem_new(cpu_env, 1296 offsetof(CPUCRISState, cc_x), "cc_x"); 1297 cc_src = tcg_global_mem_new(cpu_env, 1298 offsetof(CPUCRISState, cc_src), "cc_src"); 1299 cc_dest = tcg_global_mem_new(cpu_env, 1300 offsetof(CPUCRISState, cc_dest), 1301 "cc_dest"); 1302 cc_result = tcg_global_mem_new(cpu_env, 1303 offsetof(CPUCRISState, cc_result), 1304 "cc_result"); 1305 cc_op = tcg_global_mem_new(cpu_env, 1306 offsetof(CPUCRISState, cc_op), "cc_op"); 1307 cc_size = tcg_global_mem_new(cpu_env, 1308 offsetof(CPUCRISState, cc_size), 1309 "cc_size"); 1310 cc_mask = tcg_global_mem_new(cpu_env, 1311 offsetof(CPUCRISState, cc_mask), 1312 "cc_mask"); 1313 1314 env_pc = tcg_global_mem_new(cpu_env, 1315 offsetof(CPUCRISState, pc), 1316 "pc"); 1317 env_btarget = tcg_global_mem_new(cpu_env, 1318 offsetof(CPUCRISState, btarget), 1319 "btarget"); 1320 env_btaken = tcg_global_mem_new(cpu_env, 1321 offsetof(CPUCRISState, btaken), 1322 "btaken"); 1323 for (i = 0; i < 16; i++) { 1324 cpu_R[i] = tcg_global_mem_new(cpu_env, 1325 offsetof(CPUCRISState, regs[i]), 1326 regnames_v10[i]); 1327 } 1328 for (i = 0; i < 16; i++) { 1329 cpu_PR[i] = tcg_global_mem_new(cpu_env, 1330 offsetof(CPUCRISState, pregs[i]), 1331 pregnames_v10[i]); 1332 } 1333} 1334