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