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