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