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