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