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 *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 *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 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} 65 66static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val, 67 unsigned int size, int mem_index) 68{ 69 TCGLabel *l1 = gen_new_label(); 70 TCGv taddr = tcg_temp_local_new(); 71 TCGv tval = tcg_temp_local_new(); 72 TCGv t1 = tcg_temp_local_new(); 73 dc->postinc = 0; 74 cris_evaluate_flags(dc); 75 76 tcg_gen_mov_tl(taddr, addr); 77 tcg_gen_mov_tl(tval, val); 78 79 /* Store only if F flag isn't set */ 80 tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10); 81 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); 82 if (size == 1) { 83 tcg_gen_qemu_st8(tval, taddr, mem_index); 84 } else if (size == 2) { 85 tcg_gen_qemu_st16(tval, taddr, mem_index); 86 } else { 87 tcg_gen_qemu_st32(tval, taddr, mem_index); 88 } 89 gen_set_label(l1); 90 tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */ 91 tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/ 92 tcg_temp_free(t1); 93 tcg_temp_free(tval); 94 tcg_temp_free(taddr); 95} 96 97static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val, 98 unsigned int size) 99{ 100 int mem_index = cpu_mmu_index(&dc->cpu->env, false); 101 102 /* If we get a fault on a delayslot we must keep the jmp state in 103 the cpu-state to be able to re-execute the jmp. */ 104 if (dc->delayed_branch == 1) { 105 cris_store_direct_jmp(dc); 106 } 107 108 /* Conditional writes. We only support the kind were X is known 109 at translation time. */ 110 if (dc->flagx_known && 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 dc->flagx_known = 1; 379 if (set) 380 dc->flags_x = X_FLAG; 381 else 382 dc->flags_x = 0; 383 } 384 385 cris_evaluate_flags (dc); 386 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 387 cris_update_cc_x(dc); 388 tcg_gen_movi_tl(cc_op, dc->cc_op); 389 390 if (set) { 391 tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags); 392 } else { 393 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], 394 ~(flags|F_FLAG_V10|P_FLAG_V10)); 395 } 396 397 dc->flags_uptodate = 1; 398 dc->clear_x = 0; 399 cris_lock_irq(dc); 400 return 2; 401} 402 403static inline void dec10_reg_prep_sext(DisasContext *dc, int size, int sext, 404 TCGv dd, TCGv ds, TCGv sd, TCGv ss) 405{ 406 if (sext) { 407 t_gen_sext(dd, sd, size); 408 t_gen_sext(ds, ss, size); 409 } else { 410 t_gen_zext(dd, sd, size); 411 t_gen_zext(ds, ss, size); 412 } 413} 414 415static void dec10_reg_alu(DisasContext *dc, int op, int size, int sext) 416{ 417 TCGv t[2]; 418 419 t[0] = tcg_temp_new(); 420 t[1] = tcg_temp_new(); 421 dec10_reg_prep_sext(dc, size, sext, 422 t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]); 423 424 if (op == CC_OP_LSL || op == CC_OP_LSR || op == CC_OP_ASR) { 425 tcg_gen_andi_tl(t[1], t[1], 63); 426 } 427 428 assert(dc->dst != 15); 429 cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], size); 430 tcg_temp_free(t[0]); 431 tcg_temp_free(t[1]); 432} 433 434static void dec10_reg_bound(DisasContext *dc, int size) 435{ 436 TCGv t; 437 438 t = tcg_temp_local_new(); 439 t_gen_zext(t, cpu_R[dc->src], size); 440 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4); 441 tcg_temp_free(t); 442} 443 444static void dec10_reg_mul(DisasContext *dc, int size, int sext) 445{ 446 int op = sext ? CC_OP_MULS : CC_OP_MULU; 447 TCGv t[2]; 448 449 t[0] = tcg_temp_new(); 450 t[1] = tcg_temp_new(); 451 dec10_reg_prep_sext(dc, size, sext, 452 t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]); 453 454 cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], 4); 455 456 tcg_temp_free(t[0]); 457 tcg_temp_free(t[1]); 458} 459 460 461static void dec10_reg_movs(DisasContext *dc) 462{ 463 int size = (dc->size & 1) + 1; 464 TCGv t; 465 466 LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst); 467 cris_cc_mask(dc, CC_MASK_NZVC); 468 469 t = tcg_temp_new(); 470 if (dc->ir & 32) 471 t_gen_sext(t, cpu_R[dc->src], size); 472 else 473 t_gen_zext(t, cpu_R[dc->src], size); 474 475 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, 4); 476 tcg_temp_free(t); 477} 478 479static void dec10_reg_alux(DisasContext *dc, int op) 480{ 481 int size = (dc->size & 1) + 1; 482 TCGv t; 483 484 LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst); 485 cris_cc_mask(dc, CC_MASK_NZVC); 486 487 t = tcg_temp_new(); 488 if (dc->ir & 32) 489 t_gen_sext(t, cpu_R[dc->src], size); 490 else 491 t_gen_zext(t, cpu_R[dc->src], size); 492 493 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[dc->dst], t, 4); 494 tcg_temp_free(t); 495} 496 497static void dec10_reg_mov_pr(DisasContext *dc) 498{ 499 LOG_DIS("move p%d r%d sz=%d\n", dc->dst, dc->src, preg_sizes_v10[dc->dst]); 500 cris_lock_irq(dc); 501 if (dc->src == 15) { 502 tcg_gen_mov_tl(env_btarget, cpu_PR[dc->dst]); 503 cris_prepare_jmp(dc, JMP_INDIRECT); 504 return; 505 } 506 if (dc->dst == PR_CCS) { 507 cris_evaluate_flags(dc); 508 } 509 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], 510 cpu_R[dc->src], cpu_PR[dc->dst], preg_sizes_v10[dc->dst]); 511} 512 513static void dec10_reg_abs(DisasContext *dc) 514{ 515 TCGv t0; 516 517 LOG_DIS("abs $r%u, $r%u\n", dc->src, dc->dst); 518 519 assert(dc->dst != 15); 520 t0 = tcg_temp_new(); 521 tcg_gen_sari_tl(t0, cpu_R[dc->src], 31); 522 tcg_gen_xor_tl(cpu_R[dc->dst], cpu_R[dc->src], t0); 523 tcg_gen_sub_tl(t0, cpu_R[dc->dst], t0); 524 525 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t0, 4); 526 tcg_temp_free(t0); 527} 528 529static void dec10_reg_swap(DisasContext *dc) 530{ 531 TCGv t0; 532 533 LOG_DIS("not $r%d, $r%d\n", dc->src, dc->dst); 534 535 cris_cc_mask(dc, CC_MASK_NZVC); 536 t0 = tcg_temp_new(); 537 tcg_gen_mov_tl(t0, cpu_R[dc->src]); 538 if (dc->dst & 8) 539 tcg_gen_not_tl(t0, t0); 540 if (dc->dst & 4) 541 t_gen_swapw(t0, t0); 542 if (dc->dst & 2) 543 t_gen_swapb(t0, t0); 544 if (dc->dst & 1) 545 t_gen_swapr(t0, t0); 546 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], cpu_R[dc->src], t0, 4); 547 tcg_temp_free(t0); 548} 549 550static void dec10_reg_scc(DisasContext *dc) 551{ 552 int cond = dc->dst; 553 554 LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src); 555 556 gen_tst_cc(dc, cpu_R[dc->src], cond); 557 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->src], cpu_R[dc->src], 0); 558 559 cris_cc_mask(dc, 0); 560} 561 562static unsigned int dec10_reg(DisasContext *dc) 563{ 564 TCGv t; 565 unsigned int insn_len = 2; 566 unsigned int size = dec10_size(dc->size); 567 unsigned int tmp; 568 569 if (dc->size != 3) { 570 switch (dc->opcode) { 571 case CRISV10_REG_MOVE_R: 572 LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst); 573 cris_cc_mask(dc, CC_MASK_NZVC); 574 dec10_reg_alu(dc, CC_OP_MOVE, size, 0); 575 if (dc->dst == 15) { 576 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 577 cris_prepare_jmp(dc, JMP_INDIRECT); 578 dc->delayed_branch = 1; 579 } 580 break; 581 case CRISV10_REG_MOVX: 582 cris_cc_mask(dc, CC_MASK_NZVC); 583 dec10_reg_movs(dc); 584 break; 585 case CRISV10_REG_ADDX: 586 cris_cc_mask(dc, CC_MASK_NZVC); 587 dec10_reg_alux(dc, CC_OP_ADD); 588 break; 589 case CRISV10_REG_SUBX: 590 cris_cc_mask(dc, CC_MASK_NZVC); 591 dec10_reg_alux(dc, CC_OP_SUB); 592 break; 593 case CRISV10_REG_ADD: 594 LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 595 cris_cc_mask(dc, CC_MASK_NZVC); 596 dec10_reg_alu(dc, CC_OP_ADD, size, 0); 597 break; 598 case CRISV10_REG_SUB: 599 LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 600 cris_cc_mask(dc, CC_MASK_NZVC); 601 dec10_reg_alu(dc, CC_OP_SUB, size, 0); 602 break; 603 case CRISV10_REG_CMP: 604 LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 605 cris_cc_mask(dc, CC_MASK_NZVC); 606 dec10_reg_alu(dc, CC_OP_CMP, size, 0); 607 break; 608 case CRISV10_REG_BOUND: 609 LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 610 cris_cc_mask(dc, CC_MASK_NZVC); 611 dec10_reg_bound(dc, size); 612 break; 613 case CRISV10_REG_AND: 614 LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 615 cris_cc_mask(dc, CC_MASK_NZVC); 616 dec10_reg_alu(dc, CC_OP_AND, size, 0); 617 break; 618 case CRISV10_REG_ADDI: 619 if (dc->src == 15) { 620 /* nop. */ 621 return 2; 622 } 623 t = tcg_temp_new(); 624 LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size); 625 tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3); 626 tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t); 627 tcg_temp_free(t); 628 break; 629 case CRISV10_REG_LSL: 630 LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 631 cris_cc_mask(dc, CC_MASK_NZVC); 632 dec10_reg_alu(dc, CC_OP_LSL, size, 0); 633 break; 634 case CRISV10_REG_LSR: 635 LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 636 cris_cc_mask(dc, CC_MASK_NZVC); 637 dec10_reg_alu(dc, CC_OP_LSR, size, 0); 638 break; 639 case CRISV10_REG_ASR: 640 LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 641 cris_cc_mask(dc, CC_MASK_NZVC); 642 dec10_reg_alu(dc, CC_OP_ASR, size, 1); 643 break; 644 case CRISV10_REG_OR: 645 LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 646 cris_cc_mask(dc, CC_MASK_NZVC); 647 dec10_reg_alu(dc, CC_OP_OR, size, 0); 648 break; 649 case CRISV10_REG_NEG: 650 LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 651 cris_cc_mask(dc, CC_MASK_NZVC); 652 dec10_reg_alu(dc, CC_OP_NEG, size, 0); 653 break; 654 case CRISV10_REG_BIAP: 655 LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc, 656 dc->opcode, dc->src, dc->dst, size); 657 switch (size) { 658 case 4: tmp = 2; break; 659 case 2: tmp = 1; break; 660 case 1: tmp = 0; break; 661 default: 662 cpu_abort(CPU(dc->cpu), "Unhandled BIAP"); 663 break; 664 } 665 666 t = tcg_temp_new(); 667 tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp); 668 if (dc->src == 15) { 669 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1); 670 } else { 671 tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t); 672 } 673 tcg_temp_free(t); 674 cris_set_prefix(dc); 675 break; 676 677 default: 678 LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc, 679 dc->opcode, dc->src, dc->dst); 680 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 681 break; 682 } 683 } else { 684 switch (dc->opcode) { 685 case CRISV10_REG_MOVX: 686 cris_cc_mask(dc, CC_MASK_NZVC); 687 dec10_reg_movs(dc); 688 break; 689 case CRISV10_REG_ADDX: 690 cris_cc_mask(dc, CC_MASK_NZVC); 691 dec10_reg_alux(dc, CC_OP_ADD); 692 break; 693 case CRISV10_REG_SUBX: 694 cris_cc_mask(dc, CC_MASK_NZVC); 695 dec10_reg_alux(dc, CC_OP_SUB); 696 break; 697 case CRISV10_REG_MOVE_SPR_R: 698 cris_evaluate_flags(dc); 699 cris_cc_mask(dc, 0); 700 dec10_reg_mov_pr(dc); 701 break; 702 case CRISV10_REG_MOVE_R_SPR: 703 LOG_DIS("move r%d p%d\n", dc->src, dc->dst); 704 cris_evaluate_flags(dc); 705 if (dc->src != 11) /* fast for srp. */ 706 dc->cpustate_changed = 1; 707 t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]); 708 break; 709 case CRISV10_REG_SETF: 710 case CRISV10_REG_CLEARF: 711 dec10_setclrf(dc); 712 break; 713 case CRISV10_REG_SWAP: 714 dec10_reg_swap(dc); 715 break; 716 case CRISV10_REG_ABS: 717 cris_cc_mask(dc, CC_MASK_NZVC); 718 dec10_reg_abs(dc); 719 break; 720 case CRISV10_REG_LZ: 721 LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 722 cris_cc_mask(dc, CC_MASK_NZVC); 723 dec10_reg_alu(dc, CC_OP_LZ, 4, 0); 724 break; 725 case CRISV10_REG_XOR: 726 LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 727 cris_cc_mask(dc, CC_MASK_NZVC); 728 dec10_reg_alu(dc, CC_OP_XOR, 4, 0); 729 break; 730 case CRISV10_REG_BTST: 731 LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 732 cris_cc_mask(dc, CC_MASK_NZVC); 733 cris_update_cc_op(dc, CC_OP_FLAGS, 4); 734 gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst], 735 cpu_R[dc->src], cpu_PR[PR_CCS]); 736 break; 737 case CRISV10_REG_DSTEP: 738 LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 739 cris_cc_mask(dc, CC_MASK_NZVC); 740 cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst], 741 cpu_R[dc->dst], cpu_R[dc->src], 4); 742 break; 743 case CRISV10_REG_MSTEP: 744 LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size); 745 cris_evaluate_flags(dc); 746 cris_cc_mask(dc, CC_MASK_NZVC); 747 cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst], 748 cpu_R[dc->dst], cpu_R[dc->src], 4); 749 break; 750 case CRISV10_REG_SCC: 751 dec10_reg_scc(dc); 752 break; 753 default: 754 LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc, 755 dc->opcode, dc->src, dc->dst); 756 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 757 break; 758 } 759 } 760 return insn_len; 761} 762 763static unsigned int dec10_ind_move_m_r(CPUCRISState *env, DisasContext *dc, 764 unsigned int size) 765{ 766 unsigned int insn_len = 2; 767 TCGv t; 768 769 LOG_DIS("%s: move.%d [$r%d], $r%d\n", __func__, 770 size, dc->src, dc->dst); 771 772 cris_cc_mask(dc, CC_MASK_NZVC); 773 t = tcg_temp_new(); 774 insn_len += dec10_prep_move_m(env, dc, 0, size, t); 775 cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size); 776 if (dc->dst == 15) { 777 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 778 cris_prepare_jmp(dc, JMP_INDIRECT); 779 dc->delayed_branch = 1; 780 } 781 782 tcg_temp_free(t); 783 return insn_len; 784} 785 786static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size) 787{ 788 unsigned int insn_len = 2; 789 TCGv addr; 790 791 LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst); 792 addr = tcg_temp_new(); 793 crisv10_prepare_memaddr(dc, addr, size); 794 gen_store_v10(dc, addr, cpu_R[dc->dst], size); 795 insn_len += crisv10_post_memaddr(dc, size); 796 tcg_temp_free(addr); 797 798 return insn_len; 799} 800 801static unsigned int dec10_ind_move_m_pr(CPUCRISState *env, DisasContext *dc) 802{ 803 unsigned int insn_len = 2, rd = dc->dst; 804 TCGv t, addr; 805 806 LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src); 807 cris_lock_irq(dc); 808 809 addr = tcg_temp_new(); 810 t = tcg_temp_new(); 811 insn_len += dec10_prep_move_m(env, dc, 0, 4, t); 812 if (rd == 15) { 813 tcg_gen_mov_tl(env_btarget, t); 814 cris_prepare_jmp(dc, JMP_INDIRECT); 815 dc->delayed_branch = 1; 816 } else { 817 tcg_gen_mov_tl(cpu_PR[rd], t); 818 dc->cpustate_changed = 1; 819 } 820 tcg_temp_free(addr); 821 tcg_temp_free(t); 822 return insn_len; 823} 824 825static unsigned int dec10_ind_move_pr_m(DisasContext *dc) 826{ 827 unsigned int insn_len = 2, size = preg_sizes_v10[dc->dst]; 828 TCGv addr, t0; 829 830 LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src); 831 832 addr = tcg_temp_new(); 833 crisv10_prepare_memaddr(dc, addr, size); 834 if (dc->dst == PR_CCS) { 835 t0 = tcg_temp_new(); 836 cris_evaluate_flags(dc); 837 tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG); 838 gen_store_v10(dc, addr, t0, size); 839 tcg_temp_free(t0); 840 } else { 841 gen_store_v10(dc, addr, cpu_PR[dc->dst], size); 842 } 843 insn_len += crisv10_post_memaddr(dc, size); 844 tcg_temp_free(addr); 845 cris_lock_irq(dc); 846 847 return insn_len; 848} 849 850static void dec10_movem_r_m(DisasContext *dc) 851{ 852 int i, pfix = dc->tb_flags & PFIX_FLAG; 853 TCGv addr, t0; 854 855 LOG_DIS("%s r%d, [r%d] pi=%d ir=%x\n", __func__, 856 dc->dst, dc->src, dc->postinc, dc->ir); 857 858 addr = tcg_temp_new(); 859 t0 = tcg_temp_new(); 860 crisv10_prepare_memaddr(dc, addr, 4); 861 tcg_gen_mov_tl(t0, addr); 862 for (i = dc->dst; i >= 0; i--) { 863 if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) { 864 gen_store_v10(dc, addr, t0, 4); 865 } else { 866 gen_store_v10(dc, addr, cpu_R[i], 4); 867 } 868 tcg_gen_addi_tl(addr, addr, 4); 869 } 870 871 if (pfix && dc->mode == CRISV10_MODE_AUTOINC) { 872 tcg_gen_mov_tl(cpu_R[dc->src], t0); 873 } 874 875 if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) { 876 tcg_gen_mov_tl(cpu_R[dc->src], addr); 877 } 878 tcg_temp_free(addr); 879 tcg_temp_free(t0); 880} 881 882static void dec10_movem_m_r(DisasContext *dc) 883{ 884 int i, pfix = dc->tb_flags & PFIX_FLAG; 885 TCGv addr, t0; 886 887 LOG_DIS("%s [r%d], r%d pi=%d ir=%x\n", __func__, 888 dc->src, dc->dst, dc->postinc, dc->ir); 889 890 addr = tcg_temp_new(); 891 t0 = tcg_temp_new(); 892 crisv10_prepare_memaddr(dc, addr, 4); 893 tcg_gen_mov_tl(t0, addr); 894 for (i = dc->dst; i >= 0; i--) { 895 gen_load(dc, cpu_R[i], addr, 4, 0); 896 tcg_gen_addi_tl(addr, addr, 4); 897 } 898 899 if (pfix && dc->mode == CRISV10_MODE_AUTOINC) { 900 tcg_gen_mov_tl(cpu_R[dc->src], t0); 901 } 902 903 if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) { 904 tcg_gen_mov_tl(cpu_R[dc->src], addr); 905 } 906 tcg_temp_free(addr); 907 tcg_temp_free(t0); 908} 909 910static int dec10_ind_alu(CPUCRISState *env, DisasContext *dc, 911 int op, unsigned int size) 912{ 913 int insn_len = 0; 914 int rd = dc->dst; 915 TCGv t[2]; 916 917 cris_alu_m_alloc_temps(t); 918 insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]); 919 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size); 920 if (dc->dst == 15) { 921 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 922 cris_prepare_jmp(dc, JMP_INDIRECT); 923 dc->delayed_branch = 1; 924 return insn_len; 925 } 926 927 cris_alu_m_free_temps(t); 928 929 return insn_len; 930} 931 932static int dec10_ind_bound(CPUCRISState *env, DisasContext *dc, 933 unsigned int size) 934{ 935 int insn_len = 0; 936 int rd = dc->dst; 937 TCGv t; 938 939 t = tcg_temp_local_new(); 940 insn_len += dec10_prep_move_m(env, dc, 0, size, t); 941 cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4); 942 if (dc->dst == 15) { 943 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 944 cris_prepare_jmp(dc, JMP_INDIRECT); 945 dc->delayed_branch = 1; 946 } 947 948 tcg_temp_free(t); 949 return insn_len; 950} 951 952static int dec10_alux_m(CPUCRISState *env, DisasContext *dc, int op) 953{ 954 unsigned int size = (dc->size & 1) ? 2 : 1; 955 unsigned int sx = !!(dc->size & 2); 956 int insn_len = 2; 957 int rd = dc->dst; 958 TCGv t; 959 960 LOG_DIS("addx size=%d sx=%d op=%d %d\n", size, sx, dc->src, dc->dst); 961 962 t = tcg_temp_new(); 963 964 cris_cc_mask(dc, CC_MASK_NZVC); 965 insn_len += dec10_prep_move_m(env, dc, sx, size, t); 966 cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4); 967 if (dc->dst == 15) { 968 tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]); 969 cris_prepare_jmp(dc, JMP_INDIRECT); 970 dc->delayed_branch = 1; 971 } 972 973 tcg_temp_free(t); 974 return insn_len; 975} 976 977static int dec10_dip(CPUCRISState *env, DisasContext *dc) 978{ 979 int insn_len = 2; 980 uint32_t imm; 981 982 LOG_DIS("dip pc=%x opcode=%d r%d r%d\n", 983 dc->pc, dc->opcode, dc->src, dc->dst); 984 if (dc->src == 15) { 985 imm = cpu_ldl_code(env, dc->pc + 2); 986 tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm); 987 if (dc->postinc) 988 insn_len += 4; 989 tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len - 2); 990 } else { 991 gen_load(dc, cpu_PR[PR_PREFIX], cpu_R[dc->src], 4, 0); 992 if (dc->postinc) 993 tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], 4); 994 } 995 996 cris_set_prefix(dc); 997 return insn_len; 998} 999 1000static int dec10_bdap_m(CPUCRISState *env, DisasContext *dc, int size) 1001{ 1002 int insn_len = 2; 1003 int rd = dc->dst; 1004 1005 LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n", 1006 dc->pc, dc->opcode, dc->src, dc->dst, size); 1007 1008 assert(dc->dst != 15); 1009#if 0 1010 /* 8bit embedded offset? */ 1011 if (!dc->postinc && (dc->ir & (1 << 11))) { 1012 int simm = dc->ir & 0xff; 1013 1014 /* cpu_abort(CPU(dc->cpu), "Unhandled opcode"); */ 1015 /* sign extended. */ 1016 simm = (int8_t)simm; 1017 1018 tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm); 1019 1020 cris_set_prefix(dc); 1021 return insn_len; 1022 } 1023#endif 1024 /* Now the rest of the modes are truly indirect. */ 1025 insn_len += dec10_prep_move_m(env, dc, 1, size, cpu_PR[PR_PREFIX]); 1026 tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]); 1027 cris_set_prefix(dc); 1028 return insn_len; 1029} 1030 1031static unsigned int dec10_ind(CPUCRISState *env, DisasContext *dc) 1032{ 1033 unsigned int insn_len = 2; 1034 unsigned int size = dec10_size(dc->size); 1035 uint32_t imm; 1036 int32_t simm; 1037 TCGv t[2], c; 1038 1039 if (dc->size != 3) { 1040 switch (dc->opcode) { 1041 case CRISV10_IND_MOVE_M_R: 1042 return dec10_ind_move_m_r(env, dc, size); 1043 case CRISV10_IND_MOVE_R_M: 1044 return dec10_ind_move_r_m(dc, size); 1045 case CRISV10_IND_CMP: 1046 LOG_DIS("cmp size=%d op=%d %d\n", size, dc->src, dc->dst); 1047 cris_cc_mask(dc, CC_MASK_NZVC); 1048 insn_len += dec10_ind_alu(env, dc, CC_OP_CMP, size); 1049 break; 1050 case CRISV10_IND_TEST: 1051 LOG_DIS("test size=%d op=%d %d\n", size, dc->src, dc->dst); 1052 1053 cris_evaluate_flags(dc); 1054 cris_cc_mask(dc, CC_MASK_NZVC); 1055 cris_alu_m_alloc_temps(t); 1056 insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]); 1057 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3); 1058 c = tcg_const_tl(0); 1059 cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst], 1060 t[0], c, size); 1061 tcg_temp_free(c); 1062 cris_alu_m_free_temps(t); 1063 break; 1064 case CRISV10_IND_ADD: 1065 LOG_DIS("add size=%d op=%d %d\n", size, dc->src, dc->dst); 1066 cris_cc_mask(dc, CC_MASK_NZVC); 1067 insn_len += dec10_ind_alu(env, dc, CC_OP_ADD, size); 1068 break; 1069 case CRISV10_IND_SUB: 1070 LOG_DIS("sub size=%d op=%d %d\n", size, dc->src, dc->dst); 1071 cris_cc_mask(dc, CC_MASK_NZVC); 1072 insn_len += dec10_ind_alu(env, dc, CC_OP_SUB, size); 1073 break; 1074 case CRISV10_IND_BOUND: 1075 LOG_DIS("bound size=%d op=%d %d\n", size, dc->src, dc->dst); 1076 cris_cc_mask(dc, CC_MASK_NZVC); 1077 insn_len += dec10_ind_bound(env, dc, size); 1078 break; 1079 case CRISV10_IND_AND: 1080 LOG_DIS("and size=%d op=%d %d\n", size, dc->src, dc->dst); 1081 cris_cc_mask(dc, CC_MASK_NZVC); 1082 insn_len += dec10_ind_alu(env, dc, CC_OP_AND, size); 1083 break; 1084 case CRISV10_IND_OR: 1085 LOG_DIS("or size=%d op=%d %d\n", size, dc->src, dc->dst); 1086 cris_cc_mask(dc, CC_MASK_NZVC); 1087 insn_len += dec10_ind_alu(env, dc, CC_OP_OR, size); 1088 break; 1089 case CRISV10_IND_MOVX: 1090 insn_len = dec10_alux_m(env, dc, CC_OP_MOVE); 1091 break; 1092 case CRISV10_IND_ADDX: 1093 insn_len = dec10_alux_m(env, dc, CC_OP_ADD); 1094 break; 1095 case CRISV10_IND_SUBX: 1096 insn_len = dec10_alux_m(env, dc, CC_OP_SUB); 1097 break; 1098 case CRISV10_IND_CMPX: 1099 insn_len = dec10_alux_m(env, dc, CC_OP_CMP); 1100 break; 1101 case CRISV10_IND_MUL: 1102 /* This is a reg insn coded in the mem indir space. */ 1103 LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode); 1104 cris_cc_mask(dc, CC_MASK_NZVC); 1105 dec10_reg_mul(dc, size, dc->ir & (1 << 10)); 1106 break; 1107 case CRISV10_IND_BDAP_M: 1108 insn_len = dec10_bdap_m(env, dc, size); 1109 break; 1110 default: 1111 /* 1112 * ADDC for v17: 1113 * 1114 * Instruction format: ADDC [Rs],Rd 1115 * 1116 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1117 * |Destination(Rd)| 1 0 0 1 1 0 1 0 | Source(Rs)| 1118 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+ 1119 * 1120 * Instruction format: ADDC [Rs+],Rd 1121 * 1122 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1123 * |Destination(Rd)| 1 1 0 1 1 0 1 0 | Source(Rs)| 1124 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1125 */ 1126 if (dc->opcode == CRISV17_IND_ADDC && dc->size == 2 && 1127 env->pregs[PR_VR] == 17) { 1128 LOG_DIS("addc op=%d %d\n", dc->src, dc->dst); 1129 cris_cc_mask(dc, CC_MASK_NZVC); 1130 insn_len += dec10_ind_alu(env, dc, CC_OP_ADDC, size); 1131 break; 1132 } 1133 1134 LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n", 1135 dc->pc, size, dc->opcode, dc->src, dc->dst); 1136 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 1137 break; 1138 } 1139 return insn_len; 1140 } 1141 1142 switch (dc->opcode) { 1143 case CRISV10_IND_MOVE_M_SPR: 1144 insn_len = dec10_ind_move_m_pr(env, dc); 1145 break; 1146 case CRISV10_IND_MOVE_SPR_M: 1147 insn_len = dec10_ind_move_pr_m(dc); 1148 break; 1149 case CRISV10_IND_JUMP_M: 1150 if (dc->src == 15) { 1151 LOG_DIS("jump.%d %d r%d r%d direct\n", size, 1152 dc->opcode, dc->src, dc->dst); 1153 imm = cpu_ldl_code(env, dc->pc + 2); 1154 if (dc->mode == CRISV10_MODE_AUTOINC) 1155 insn_len += size; 1156 1157 c = tcg_const_tl(dc->pc + insn_len); 1158 t_gen_mov_preg_TN(dc, dc->dst, c); 1159 tcg_temp_free(c); 1160 dc->jmp_pc = imm; 1161 cris_prepare_jmp(dc, JMP_DIRECT); 1162 dc->delayed_branch--; /* v10 has no dslot here. */ 1163 } else { 1164 if (dc->dst == 14) { 1165 LOG_DIS("break %d\n", dc->src); 1166 cris_evaluate_flags(dc); 1167 tcg_gen_movi_tl(env_pc, dc->pc + 2); 1168 c = tcg_const_tl(dc->src + 2); 1169 t_gen_mov_env_TN(trap_vector, c); 1170 tcg_temp_free(c); 1171 t_gen_raise_exception(EXCP_BREAK); 1172 dc->is_jmp = DISAS_UPDATE; 1173 return insn_len; 1174 } 1175 LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size, 1176 dc->opcode, dc->src, dc->dst); 1177 t[0] = tcg_temp_new(); 1178 c = tcg_const_tl(dc->pc + insn_len); 1179 t_gen_mov_preg_TN(dc, dc->dst, c); 1180 tcg_temp_free(c); 1181 crisv10_prepare_memaddr(dc, t[0], size); 1182 gen_load(dc, env_btarget, t[0], 4, 0); 1183 insn_len += crisv10_post_memaddr(dc, size); 1184 cris_prepare_jmp(dc, JMP_INDIRECT); 1185 dc->delayed_branch--; /* v10 has no dslot here. */ 1186 tcg_temp_free(t[0]); 1187 } 1188 break; 1189 1190 case CRISV10_IND_MOVEM_R_M: 1191 LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n", 1192 dc->pc, dc->opcode, dc->dst, dc->src); 1193 dec10_movem_r_m(dc); 1194 break; 1195 case CRISV10_IND_MOVEM_M_R: 1196 LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode); 1197 dec10_movem_m_r(dc); 1198 break; 1199 case CRISV10_IND_JUMP_R: 1200 LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n", 1201 dc->pc, dc->opcode, dc->dst, dc->src); 1202 tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]); 1203 c = tcg_const_tl(dc->pc + insn_len); 1204 t_gen_mov_preg_TN(dc, dc->dst, c); 1205 tcg_temp_free(c); 1206 cris_prepare_jmp(dc, JMP_INDIRECT); 1207 dc->delayed_branch--; /* v10 has no dslot here. */ 1208 break; 1209 case CRISV10_IND_MOVX: 1210 insn_len = dec10_alux_m(env, dc, CC_OP_MOVE); 1211 break; 1212 case CRISV10_IND_ADDX: 1213 insn_len = dec10_alux_m(env, dc, CC_OP_ADD); 1214 break; 1215 case CRISV10_IND_SUBX: 1216 insn_len = dec10_alux_m(env, dc, CC_OP_SUB); 1217 break; 1218 case CRISV10_IND_CMPX: 1219 insn_len = dec10_alux_m(env, dc, CC_OP_CMP); 1220 break; 1221 case CRISV10_IND_DIP: 1222 insn_len = dec10_dip(env, dc); 1223 break; 1224 case CRISV10_IND_BCC_M: 1225 1226 cris_cc_mask(dc, 0); 1227 simm = cpu_ldsw_code(env, dc->pc + 2); 1228 simm += 4; 1229 1230 LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm); 1231 cris_prepare_cc_branch(dc, simm, dc->cond); 1232 insn_len = 4; 1233 break; 1234 default: 1235 LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode); 1236 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 1237 break; 1238 } 1239 1240 return insn_len; 1241} 1242 1243static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc) 1244{ 1245 unsigned int insn_len = 2; 1246 1247 /* Load a halfword onto the instruction register. */ 1248 dc->ir = cpu_lduw_code(env, dc->pc); 1249 1250 /* Now decode it. */ 1251 dc->opcode = EXTRACT_FIELD(dc->ir, 6, 9); 1252 dc->mode = EXTRACT_FIELD(dc->ir, 10, 11); 1253 dc->src = EXTRACT_FIELD(dc->ir, 0, 3); 1254 dc->size = EXTRACT_FIELD(dc->ir, 4, 5); 1255 dc->cond = dc->dst = EXTRACT_FIELD(dc->ir, 12, 15); 1256 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10); 1257 1258 dc->clear_prefix = 1; 1259 1260 /* FIXME: What if this insn insn't 2 in length?? */ 1261 if (dc->src == 15 || dc->dst == 15) 1262 tcg_gen_movi_tl(cpu_R[15], dc->pc + 2); 1263 1264 switch (dc->mode) { 1265 case CRISV10_MODE_QIMMEDIATE: 1266 insn_len = dec10_quick_imm(dc); 1267 break; 1268 case CRISV10_MODE_REG: 1269 insn_len = dec10_reg(dc); 1270 break; 1271 case CRISV10_MODE_AUTOINC: 1272 case CRISV10_MODE_INDIRECT: 1273 insn_len = dec10_ind(env, dc); 1274 break; 1275 } 1276 1277 if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) { 1278 dc->tb_flags &= ~PFIX_FLAG; 1279 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG); 1280 if (dc->tb_flags != dc->tb->flags) { 1281 dc->cpustate_changed = 1; 1282 } 1283 } 1284 1285 /* CRISv10 locks out interrupts on dslots. */ 1286 if (dc->delayed_branch == 2) { 1287 cris_lock_irq(dc); 1288 } 1289 return insn_len; 1290} 1291 1292void cris_initialize_crisv10_tcg(void) 1293{ 1294 int i; 1295 1296 cc_x = tcg_global_mem_new(cpu_env, 1297 offsetof(CPUCRISState, cc_x), "cc_x"); 1298 cc_src = tcg_global_mem_new(cpu_env, 1299 offsetof(CPUCRISState, cc_src), "cc_src"); 1300 cc_dest = tcg_global_mem_new(cpu_env, 1301 offsetof(CPUCRISState, cc_dest), 1302 "cc_dest"); 1303 cc_result = tcg_global_mem_new(cpu_env, 1304 offsetof(CPUCRISState, cc_result), 1305 "cc_result"); 1306 cc_op = tcg_global_mem_new(cpu_env, 1307 offsetof(CPUCRISState, cc_op), "cc_op"); 1308 cc_size = tcg_global_mem_new(cpu_env, 1309 offsetof(CPUCRISState, cc_size), 1310 "cc_size"); 1311 cc_mask = tcg_global_mem_new(cpu_env, 1312 offsetof(CPUCRISState, cc_mask), 1313 "cc_mask"); 1314 1315 env_pc = tcg_global_mem_new(cpu_env, 1316 offsetof(CPUCRISState, pc), 1317 "pc"); 1318 env_btarget = tcg_global_mem_new(cpu_env, 1319 offsetof(CPUCRISState, btarget), 1320 "btarget"); 1321 env_btaken = tcg_global_mem_new(cpu_env, 1322 offsetof(CPUCRISState, btaken), 1323 "btaken"); 1324 for (i = 0; i < 16; i++) { 1325 cpu_R[i] = tcg_global_mem_new(cpu_env, 1326 offsetof(CPUCRISState, regs[i]), 1327 regnames_v10[i]); 1328 } 1329 for (i = 0; i < 16; i++) { 1330 cpu_PR[i] = tcg_global_mem_new(cpu_env, 1331 offsetof(CPUCRISState, pregs[i]), 1332 pregnames_v10[i]); 1333 } 1334} 1335