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 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 break; 1030 case CRISV10_IND_MOVE_R_M: 1031 return dec10_ind_move_r_m(dc, size); 1032 break; 1033 case CRISV10_IND_CMP: 1034 LOG_DIS("cmp size=%d op=%d %d\n", size, dc->src, dc->dst); 1035 cris_cc_mask(dc, CC_MASK_NZVC); 1036 insn_len += dec10_ind_alu(env, dc, CC_OP_CMP, size); 1037 break; 1038 case CRISV10_IND_TEST: 1039 LOG_DIS("test size=%d op=%d %d\n", size, dc->src, dc->dst); 1040 1041 cris_evaluate_flags(dc); 1042 cris_cc_mask(dc, CC_MASK_NZVC); 1043 cris_alu_m_alloc_temps(t); 1044 insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]); 1045 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3); 1046 cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst], 1047 t[0], tcg_const_tl(0), size); 1048 cris_alu_m_free_temps(t); 1049 break; 1050 case CRISV10_IND_ADD: 1051 LOG_DIS("add size=%d op=%d %d\n", size, dc->src, dc->dst); 1052 cris_cc_mask(dc, CC_MASK_NZVC); 1053 insn_len += dec10_ind_alu(env, dc, CC_OP_ADD, size); 1054 break; 1055 case CRISV10_IND_SUB: 1056 LOG_DIS("sub size=%d op=%d %d\n", size, dc->src, dc->dst); 1057 cris_cc_mask(dc, CC_MASK_NZVC); 1058 insn_len += dec10_ind_alu(env, dc, CC_OP_SUB, size); 1059 break; 1060 case CRISV10_IND_BOUND: 1061 LOG_DIS("bound size=%d op=%d %d\n", size, dc->src, dc->dst); 1062 cris_cc_mask(dc, CC_MASK_NZVC); 1063 insn_len += dec10_ind_bound(env, dc, size); 1064 break; 1065 case CRISV10_IND_AND: 1066 LOG_DIS("and size=%d op=%d %d\n", size, dc->src, dc->dst); 1067 cris_cc_mask(dc, CC_MASK_NZVC); 1068 insn_len += dec10_ind_alu(env, dc, CC_OP_AND, size); 1069 break; 1070 case CRISV10_IND_OR: 1071 LOG_DIS("or size=%d op=%d %d\n", size, dc->src, dc->dst); 1072 cris_cc_mask(dc, CC_MASK_NZVC); 1073 insn_len += dec10_ind_alu(env, dc, CC_OP_OR, size); 1074 break; 1075 case CRISV10_IND_MOVX: 1076 insn_len = dec10_alux_m(env, dc, CC_OP_MOVE); 1077 break; 1078 case CRISV10_IND_ADDX: 1079 insn_len = dec10_alux_m(env, dc, CC_OP_ADD); 1080 break; 1081 case CRISV10_IND_SUBX: 1082 insn_len = dec10_alux_m(env, dc, CC_OP_SUB); 1083 break; 1084 case CRISV10_IND_CMPX: 1085 insn_len = dec10_alux_m(env, dc, CC_OP_CMP); 1086 break; 1087 case CRISV10_IND_MUL: 1088 /* This is a reg insn coded in the mem indir space. */ 1089 LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode); 1090 cris_cc_mask(dc, CC_MASK_NZVC); 1091 dec10_reg_mul(dc, size, dc->ir & (1 << 10)); 1092 break; 1093 case CRISV10_IND_BDAP_M: 1094 insn_len = dec10_bdap_m(env, dc, size); 1095 break; 1096 default: 1097 /* 1098 * ADDC for v17: 1099 * 1100 * Instruction format: ADDC [Rs],Rd 1101 * 1102 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1103 * |Destination(Rd)| 1 0 0 1 1 0 1 0 | Source(Rs)| 1104 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+ 1105 * 1106 * Instruction format: ADDC [Rs+],Rd 1107 * 1108 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1109 * |Destination(Rd)| 1 1 0 1 1 0 1 0 | Source(Rs)| 1110 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-+ 1111 */ 1112 if (dc->opcode == CRISV17_IND_ADDC && dc->size == 2 && 1113 env->pregs[PR_VR] == 17) { 1114 LOG_DIS("addc op=%d %d\n", dc->src, dc->dst); 1115 cris_cc_mask(dc, CC_MASK_NZVC); 1116 insn_len += dec10_ind_alu(env, dc, CC_OP_ADDC, size); 1117 break; 1118 } 1119 1120 LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n", 1121 dc->pc, size, dc->opcode, dc->src, dc->dst); 1122 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 1123 break; 1124 } 1125 return insn_len; 1126 } 1127 1128 switch (dc->opcode) { 1129 case CRISV10_IND_MOVE_M_SPR: 1130 insn_len = dec10_ind_move_m_pr(env, dc); 1131 break; 1132 case CRISV10_IND_MOVE_SPR_M: 1133 insn_len = dec10_ind_move_pr_m(dc); 1134 break; 1135 case CRISV10_IND_JUMP_M: 1136 if (dc->src == 15) { 1137 LOG_DIS("jump.%d %d r%d r%d direct\n", size, 1138 dc->opcode, dc->src, dc->dst); 1139 imm = cpu_ldl_code(env, dc->pc + 2); 1140 if (dc->mode == CRISV10_MODE_AUTOINC) 1141 insn_len += size; 1142 1143 t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len)); 1144 dc->jmp_pc = imm; 1145 cris_prepare_jmp(dc, JMP_DIRECT); 1146 dc->delayed_branch--; /* v10 has no dslot here. */ 1147 } else { 1148 if (dc->dst == 14) { 1149 LOG_DIS("break %d\n", dc->src); 1150 cris_evaluate_flags(dc); 1151 tcg_gen_movi_tl(env_pc, dc->pc + 2); 1152 t_gen_mov_env_TN(trap_vector, tcg_const_tl(dc->src + 2)); 1153 t_gen_raise_exception(EXCP_BREAK); 1154 dc->is_jmp = DISAS_UPDATE; 1155 return insn_len; 1156 } 1157 LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size, 1158 dc->opcode, dc->src, dc->dst); 1159 t[0] = tcg_temp_new(); 1160 t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len)); 1161 crisv10_prepare_memaddr(dc, t[0], size); 1162 gen_load(dc, env_btarget, t[0], 4, 0); 1163 insn_len += crisv10_post_memaddr(dc, size); 1164 cris_prepare_jmp(dc, JMP_INDIRECT); 1165 dc->delayed_branch--; /* v10 has no dslot here. */ 1166 tcg_temp_free(t[0]); 1167 } 1168 break; 1169 1170 case CRISV10_IND_MOVEM_R_M: 1171 LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n", 1172 dc->pc, dc->opcode, dc->dst, dc->src); 1173 dec10_movem_r_m(dc); 1174 break; 1175 case CRISV10_IND_MOVEM_M_R: 1176 LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode); 1177 dec10_movem_m_r(dc); 1178 break; 1179 case CRISV10_IND_JUMP_R: 1180 LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n", 1181 dc->pc, dc->opcode, dc->dst, dc->src); 1182 tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]); 1183 t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len)); 1184 cris_prepare_jmp(dc, JMP_INDIRECT); 1185 dc->delayed_branch--; /* v10 has no dslot here. */ 1186 break; 1187 case CRISV10_IND_MOVX: 1188 insn_len = dec10_alux_m(env, dc, CC_OP_MOVE); 1189 break; 1190 case CRISV10_IND_ADDX: 1191 insn_len = dec10_alux_m(env, dc, CC_OP_ADD); 1192 break; 1193 case CRISV10_IND_SUBX: 1194 insn_len = dec10_alux_m(env, dc, CC_OP_SUB); 1195 break; 1196 case CRISV10_IND_CMPX: 1197 insn_len = dec10_alux_m(env, dc, CC_OP_CMP); 1198 break; 1199 case CRISV10_IND_DIP: 1200 insn_len = dec10_dip(env, dc); 1201 break; 1202 case CRISV10_IND_BCC_M: 1203 1204 cris_cc_mask(dc, 0); 1205 simm = cpu_ldsw_code(env, dc->pc + 2); 1206 simm += 4; 1207 1208 LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm); 1209 cris_prepare_cc_branch(dc, simm, dc->cond); 1210 insn_len = 4; 1211 break; 1212 default: 1213 LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode); 1214 cpu_abort(CPU(dc->cpu), "Unhandled opcode"); 1215 break; 1216 } 1217 1218 return insn_len; 1219} 1220 1221static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc) 1222{ 1223 unsigned int insn_len = 2; 1224 1225 /* Load a halfword onto the instruction register. */ 1226 dc->ir = cpu_lduw_code(env, dc->pc); 1227 1228 /* Now decode it. */ 1229 dc->opcode = EXTRACT_FIELD(dc->ir, 6, 9); 1230 dc->mode = EXTRACT_FIELD(dc->ir, 10, 11); 1231 dc->src = EXTRACT_FIELD(dc->ir, 0, 3); 1232 dc->size = EXTRACT_FIELD(dc->ir, 4, 5); 1233 dc->cond = dc->dst = EXTRACT_FIELD(dc->ir, 12, 15); 1234 dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10); 1235 1236 dc->clear_prefix = 1; 1237 1238 /* FIXME: What if this insn insn't 2 in length?? */ 1239 if (dc->src == 15 || dc->dst == 15) 1240 tcg_gen_movi_tl(cpu_R[15], dc->pc + 2); 1241 1242 switch (dc->mode) { 1243 case CRISV10_MODE_QIMMEDIATE: 1244 insn_len = dec10_quick_imm(dc); 1245 break; 1246 case CRISV10_MODE_REG: 1247 insn_len = dec10_reg(dc); 1248 break; 1249 case CRISV10_MODE_AUTOINC: 1250 case CRISV10_MODE_INDIRECT: 1251 insn_len = dec10_ind(env, dc); 1252 break; 1253 } 1254 1255 if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) { 1256 dc->tb_flags &= ~PFIX_FLAG; 1257 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG); 1258 if (dc->tb_flags != dc->tb->flags) { 1259 dc->cpustate_changed = 1; 1260 } 1261 } 1262 1263 /* CRISv10 locks out interrupts on dslots. */ 1264 if (dc->delayed_branch == 2) { 1265 cris_lock_irq(dc); 1266 } 1267 return insn_len; 1268} 1269 1270void cris_initialize_crisv10_tcg(void) 1271{ 1272 int i; 1273 1274 cc_x = tcg_global_mem_new(cpu_env, 1275 offsetof(CPUCRISState, cc_x), "cc_x"); 1276 cc_src = tcg_global_mem_new(cpu_env, 1277 offsetof(CPUCRISState, cc_src), "cc_src"); 1278 cc_dest = tcg_global_mem_new(cpu_env, 1279 offsetof(CPUCRISState, cc_dest), 1280 "cc_dest"); 1281 cc_result = tcg_global_mem_new(cpu_env, 1282 offsetof(CPUCRISState, cc_result), 1283 "cc_result"); 1284 cc_op = tcg_global_mem_new(cpu_env, 1285 offsetof(CPUCRISState, cc_op), "cc_op"); 1286 cc_size = tcg_global_mem_new(cpu_env, 1287 offsetof(CPUCRISState, cc_size), 1288 "cc_size"); 1289 cc_mask = tcg_global_mem_new(cpu_env, 1290 offsetof(CPUCRISState, cc_mask), 1291 "cc_mask"); 1292 1293 env_pc = tcg_global_mem_new(cpu_env, 1294 offsetof(CPUCRISState, pc), 1295 "pc"); 1296 env_btarget = tcg_global_mem_new(cpu_env, 1297 offsetof(CPUCRISState, btarget), 1298 "btarget"); 1299 env_btaken = tcg_global_mem_new(cpu_env, 1300 offsetof(CPUCRISState, btaken), 1301 "btaken"); 1302 for (i = 0; i < 16; i++) { 1303 cpu_R[i] = tcg_global_mem_new(cpu_env, 1304 offsetof(CPUCRISState, regs[i]), 1305 regnames_v10[i]); 1306 } 1307 for (i = 0; i < 16; i++) { 1308 cpu_PR[i] = tcg_global_mem_new(cpu_env, 1309 offsetof(CPUCRISState, pregs[i]), 1310 pregnames_v10[i]); 1311 } 1312} 1313