1 /* 2 * OpenRISC translation 3 * 4 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> 5 * Feng Gao <gf91597@gmail.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "qemu/osdep.h" 22 #include "cpu.h" 23 #include "exec/exec-all.h" 24 #include "disas/disas.h" 25 #include "tcg-op.h" 26 #include "qemu-common.h" 27 #include "qemu/log.h" 28 #include "qemu/bitops.h" 29 #include "exec/cpu_ldst.h" 30 31 #include "exec/helper-proto.h" 32 #include "exec/helper-gen.h" 33 34 #include "trace-tcg.h" 35 #include "exec/log.h" 36 37 38 #define OPENRISC_DISAS 39 40 #ifdef OPENRISC_DISAS 41 # define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) 42 #else 43 # define LOG_DIS(...) do { } while (0) 44 #endif 45 46 typedef struct DisasContext { 47 TranslationBlock *tb; 48 target_ulong pc, ppc, npc; 49 uint32_t tb_flags, synced_flags, flags; 50 uint32_t is_jmp; 51 uint32_t mem_idx; 52 int singlestep_enabled; 53 uint32_t delayed_branch; 54 } DisasContext; 55 56 static TCGv_env cpu_env; 57 static TCGv cpu_sr; 58 static TCGv cpu_R[32]; 59 static TCGv cpu_pc; 60 static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ 61 static TCGv cpu_npc; 62 static TCGv cpu_ppc; 63 static TCGv_i32 env_btaken; /* bf/bnf , F flag taken */ 64 static TCGv_i32 fpcsr; 65 static TCGv machi, maclo; 66 static TCGv fpmaddhi, fpmaddlo; 67 static TCGv_i32 env_flags; 68 #include "exec/gen-icount.h" 69 70 void openrisc_translate_init(void) 71 { 72 static const char * const regnames[] = { 73 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 74 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 75 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 76 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 77 }; 78 int i; 79 80 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); 81 tcg_ctx.tcg_env = cpu_env; 82 cpu_sr = tcg_global_mem_new(cpu_env, 83 offsetof(CPUOpenRISCState, sr), "sr"); 84 env_flags = tcg_global_mem_new_i32(cpu_env, 85 offsetof(CPUOpenRISCState, flags), 86 "flags"); 87 cpu_pc = tcg_global_mem_new(cpu_env, 88 offsetof(CPUOpenRISCState, pc), "pc"); 89 cpu_npc = tcg_global_mem_new(cpu_env, 90 offsetof(CPUOpenRISCState, npc), "npc"); 91 cpu_ppc = tcg_global_mem_new(cpu_env, 92 offsetof(CPUOpenRISCState, ppc), "ppc"); 93 jmp_pc = tcg_global_mem_new(cpu_env, 94 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc"); 95 env_btaken = tcg_global_mem_new_i32(cpu_env, 96 offsetof(CPUOpenRISCState, btaken), 97 "btaken"); 98 fpcsr = tcg_global_mem_new_i32(cpu_env, 99 offsetof(CPUOpenRISCState, fpcsr), 100 "fpcsr"); 101 machi = tcg_global_mem_new(cpu_env, 102 offsetof(CPUOpenRISCState, machi), 103 "machi"); 104 maclo = tcg_global_mem_new(cpu_env, 105 offsetof(CPUOpenRISCState, maclo), 106 "maclo"); 107 fpmaddhi = tcg_global_mem_new(cpu_env, 108 offsetof(CPUOpenRISCState, fpmaddhi), 109 "fpmaddhi"); 110 fpmaddlo = tcg_global_mem_new(cpu_env, 111 offsetof(CPUOpenRISCState, fpmaddlo), 112 "fpmaddlo"); 113 for (i = 0; i < 32; i++) { 114 cpu_R[i] = tcg_global_mem_new(cpu_env, 115 offsetof(CPUOpenRISCState, gpr[i]), 116 regnames[i]); 117 } 118 } 119 120 /* Writeback SR_F translation space to execution space. */ 121 static inline void wb_SR_F(void) 122 { 123 TCGLabel *label = gen_new_label(); 124 tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F); 125 tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label); 126 tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F); 127 gen_set_label(label); 128 } 129 130 static inline int zero_extend(unsigned int val, int width) 131 { 132 return val & ((1 << width) - 1); 133 } 134 135 static inline int sign_extend(unsigned int val, int width) 136 { 137 int sval; 138 139 /* LSL */ 140 val <<= TARGET_LONG_BITS - width; 141 sval = val; 142 /* ASR. */ 143 sval >>= TARGET_LONG_BITS - width; 144 return sval; 145 } 146 147 static inline void gen_sync_flags(DisasContext *dc) 148 { 149 /* Sync the tb dependent flag between translate and runtime. */ 150 if (dc->tb_flags != dc->synced_flags) { 151 tcg_gen_movi_tl(env_flags, dc->tb_flags); 152 dc->synced_flags = dc->tb_flags; 153 } 154 } 155 156 static void gen_exception(DisasContext *dc, unsigned int excp) 157 { 158 TCGv_i32 tmp = tcg_const_i32(excp); 159 gen_helper_exception(cpu_env, tmp); 160 tcg_temp_free_i32(tmp); 161 } 162 163 static void gen_illegal_exception(DisasContext *dc) 164 { 165 tcg_gen_movi_tl(cpu_pc, dc->pc); 166 gen_exception(dc, EXCP_ILLEGAL); 167 dc->is_jmp = DISAS_UPDATE; 168 } 169 170 /* not used yet, open it when we need or64. */ 171 /*#ifdef TARGET_OPENRISC64 172 static void check_ob64s(DisasContext *dc) 173 { 174 if (!(dc->flags & CPUCFGR_OB64S)) { 175 gen_illegal_exception(dc); 176 } 177 } 178 179 static void check_of64s(DisasContext *dc) 180 { 181 if (!(dc->flags & CPUCFGR_OF64S)) { 182 gen_illegal_exception(dc); 183 } 184 } 185 186 static void check_ov64s(DisasContext *dc) 187 { 188 if (!(dc->flags & CPUCFGR_OV64S)) { 189 gen_illegal_exception(dc); 190 } 191 } 192 #endif*/ 193 194 static inline bool use_goto_tb(DisasContext *dc, target_ulong dest) 195 { 196 if (unlikely(dc->singlestep_enabled)) { 197 return false; 198 } 199 200 #ifndef CONFIG_USER_ONLY 201 return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); 202 #else 203 return true; 204 #endif 205 } 206 207 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) 208 { 209 if (use_goto_tb(dc, dest)) { 210 tcg_gen_movi_tl(cpu_pc, dest); 211 tcg_gen_goto_tb(n); 212 tcg_gen_exit_tb((uintptr_t)dc->tb + n); 213 } else { 214 tcg_gen_movi_tl(cpu_pc, dest); 215 if (dc->singlestep_enabled) { 216 gen_exception(dc, EXCP_DEBUG); 217 } 218 tcg_gen_exit_tb(0); 219 } 220 } 221 222 static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0) 223 { 224 target_ulong tmp_pc; 225 /* N26, 26bits imm */ 226 tmp_pc = sign_extend((imm<<2), 26) + dc->pc; 227 228 switch (op0) { 229 case 0x00: /* l.j */ 230 tcg_gen_movi_tl(jmp_pc, tmp_pc); 231 break; 232 case 0x01: /* l.jal */ 233 tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); 234 tcg_gen_movi_tl(jmp_pc, tmp_pc); 235 break; 236 case 0x03: /* l.bnf */ 237 case 0x04: /* l.bf */ 238 { 239 TCGLabel *lab = gen_new_label(); 240 TCGv sr_f = tcg_temp_new(); 241 tcg_gen_movi_tl(jmp_pc, dc->pc+8); 242 tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); 243 tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE, 244 sr_f, SR_F, lab); 245 tcg_gen_movi_tl(jmp_pc, tmp_pc); 246 gen_set_label(lab); 247 tcg_temp_free(sr_f); 248 } 249 break; 250 case 0x11: /* l.jr */ 251 tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 252 break; 253 case 0x12: /* l.jalr */ 254 tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8)); 255 tcg_gen_mov_tl(jmp_pc, cpu_R[reg]); 256 break; 257 default: 258 gen_illegal_exception(dc); 259 break; 260 } 261 262 dc->delayed_branch = 2; 263 dc->tb_flags |= D_FLAG; 264 gen_sync_flags(dc); 265 } 266 267 268 static void dec_calc(DisasContext *dc, uint32_t insn) 269 { 270 uint32_t op0, op1, op2; 271 uint32_t ra, rb, rd; 272 op0 = extract32(insn, 0, 4); 273 op1 = extract32(insn, 8, 2); 274 op2 = extract32(insn, 6, 2); 275 ra = extract32(insn, 16, 5); 276 rb = extract32(insn, 11, 5); 277 rd = extract32(insn, 21, 5); 278 279 switch (op0) { 280 case 0x0000: 281 switch (op1) { 282 case 0x00: /* l.add */ 283 LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb); 284 { 285 TCGLabel *lab = gen_new_label(); 286 TCGv_i64 ta = tcg_temp_new_i64(); 287 TCGv_i64 tb = tcg_temp_new_i64(); 288 TCGv_i64 td = tcg_temp_local_new_i64(); 289 TCGv_i32 res = tcg_temp_local_new_i32(); 290 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 291 tcg_gen_extu_i32_i64(ta, cpu_R[ra]); 292 tcg_gen_extu_i32_i64(tb, cpu_R[rb]); 293 tcg_gen_add_i64(td, ta, tb); 294 tcg_gen_extrl_i64_i32(res, td); 295 tcg_gen_shri_i64(td, td, 31); 296 tcg_gen_andi_i64(td, td, 0x3); 297 /* Jump to lab when no overflow. */ 298 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); 299 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); 300 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 301 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); 302 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); 303 gen_exception(dc, EXCP_RANGE); 304 gen_set_label(lab); 305 tcg_gen_mov_i32(cpu_R[rd], res); 306 tcg_temp_free_i64(ta); 307 tcg_temp_free_i64(tb); 308 tcg_temp_free_i64(td); 309 tcg_temp_free_i32(res); 310 tcg_temp_free_i32(sr_ove); 311 } 312 break; 313 default: 314 gen_illegal_exception(dc); 315 break; 316 } 317 break; 318 319 case 0x0001: /* l.addc */ 320 switch (op1) { 321 case 0x00: 322 LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb); 323 { 324 TCGLabel *lab = gen_new_label(); 325 TCGv_i64 ta = tcg_temp_new_i64(); 326 TCGv_i64 tb = tcg_temp_new_i64(); 327 TCGv_i64 tcy = tcg_temp_local_new_i64(); 328 TCGv_i64 td = tcg_temp_local_new_i64(); 329 TCGv_i32 res = tcg_temp_local_new_i32(); 330 TCGv_i32 sr_cy = tcg_temp_local_new_i32(); 331 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 332 tcg_gen_extu_i32_i64(ta, cpu_R[ra]); 333 tcg_gen_extu_i32_i64(tb, cpu_R[rb]); 334 tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY); 335 tcg_gen_extu_i32_i64(tcy, sr_cy); 336 tcg_gen_shri_i64(tcy, tcy, 10); 337 tcg_gen_add_i64(td, ta, tb); 338 tcg_gen_add_i64(td, td, tcy); 339 tcg_gen_extrl_i64_i32(res, td); 340 tcg_gen_shri_i64(td, td, 32); 341 tcg_gen_andi_i64(td, td, 0x3); 342 /* Jump to lab when no overflow. */ 343 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); 344 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); 345 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 346 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); 347 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); 348 gen_exception(dc, EXCP_RANGE); 349 gen_set_label(lab); 350 tcg_gen_mov_i32(cpu_R[rd], res); 351 tcg_temp_free_i64(ta); 352 tcg_temp_free_i64(tb); 353 tcg_temp_free_i64(tcy); 354 tcg_temp_free_i64(td); 355 tcg_temp_free_i32(res); 356 tcg_temp_free_i32(sr_cy); 357 tcg_temp_free_i32(sr_ove); 358 } 359 break; 360 default: 361 gen_illegal_exception(dc); 362 break; 363 } 364 break; 365 366 case 0x0002: /* l.sub */ 367 switch (op1) { 368 case 0x00: 369 LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb); 370 { 371 TCGLabel *lab = gen_new_label(); 372 TCGv_i64 ta = tcg_temp_new_i64(); 373 TCGv_i64 tb = tcg_temp_new_i64(); 374 TCGv_i64 td = tcg_temp_local_new_i64(); 375 TCGv_i32 res = tcg_temp_local_new_i32(); 376 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 377 378 tcg_gen_extu_i32_i64(ta, cpu_R[ra]); 379 tcg_gen_extu_i32_i64(tb, cpu_R[rb]); 380 tcg_gen_sub_i64(td, ta, tb); 381 tcg_gen_extrl_i64_i32(res, td); 382 tcg_gen_shri_i64(td, td, 31); 383 tcg_gen_andi_i64(td, td, 0x3); 384 /* Jump to lab when no overflow. */ 385 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); 386 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); 387 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 388 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); 389 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); 390 gen_exception(dc, EXCP_RANGE); 391 gen_set_label(lab); 392 tcg_gen_mov_i32(cpu_R[rd], res); 393 tcg_temp_free_i64(ta); 394 tcg_temp_free_i64(tb); 395 tcg_temp_free_i64(td); 396 tcg_temp_free_i32(res); 397 tcg_temp_free_i32(sr_ove); 398 } 399 break; 400 default: 401 gen_illegal_exception(dc); 402 break; 403 } 404 break; 405 406 case 0x0003: /* l.and */ 407 switch (op1) { 408 case 0x00: 409 LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb); 410 tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 411 break; 412 default: 413 gen_illegal_exception(dc); 414 break; 415 } 416 break; 417 418 case 0x0004: /* l.or */ 419 switch (op1) { 420 case 0x00: 421 LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb); 422 tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 423 break; 424 default: 425 gen_illegal_exception(dc); 426 break; 427 } 428 break; 429 430 case 0x0005: 431 switch (op1) { 432 case 0x00: /* l.xor */ 433 LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb); 434 tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 435 break; 436 default: 437 gen_illegal_exception(dc); 438 break; 439 } 440 break; 441 442 case 0x0006: 443 switch (op1) { 444 case 0x03: /* l.mul */ 445 LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb); 446 if (ra != 0 && rb != 0) { 447 gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 448 } else { 449 tcg_gen_movi_tl(cpu_R[rd], 0x0); 450 } 451 break; 452 default: 453 gen_illegal_exception(dc); 454 break; 455 } 456 break; 457 458 case 0x0009: 459 switch (op1) { 460 case 0x03: /* l.div */ 461 LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb); 462 { 463 TCGLabel *lab0 = gen_new_label(); 464 TCGLabel *lab1 = gen_new_label(); 465 TCGLabel *lab2 = gen_new_label(); 466 TCGLabel *lab3 = gen_new_label(); 467 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 468 if (rb == 0) { 469 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 470 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); 471 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0); 472 gen_exception(dc, EXCP_RANGE); 473 gen_set_label(lab0); 474 } else { 475 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb], 476 0x00000000, lab1); 477 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra], 478 0x80000000, lab2); 479 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb], 480 0xffffffff, lab2); 481 gen_set_label(lab1); 482 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 483 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); 484 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab3); 485 gen_exception(dc, EXCP_RANGE); 486 gen_set_label(lab2); 487 tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 488 gen_set_label(lab3); 489 } 490 tcg_temp_free_i32(sr_ove); 491 } 492 break; 493 494 default: 495 gen_illegal_exception(dc); 496 break; 497 } 498 break; 499 500 case 0x000a: 501 switch (op1) { 502 case 0x03: /* l.divu */ 503 LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb); 504 { 505 TCGLabel *lab0 = gen_new_label(); 506 TCGLabel *lab1 = gen_new_label(); 507 TCGLabel *lab2 = gen_new_label(); 508 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 509 if (rb == 0) { 510 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 511 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); 512 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0); 513 gen_exception(dc, EXCP_RANGE); 514 gen_set_label(lab0); 515 } else { 516 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb], 517 0x00000000, lab1); 518 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 519 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); 520 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2); 521 gen_exception(dc, EXCP_RANGE); 522 gen_set_label(lab1); 523 tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 524 gen_set_label(lab2); 525 } 526 tcg_temp_free_i32(sr_ove); 527 } 528 break; 529 530 default: 531 gen_illegal_exception(dc); 532 break; 533 } 534 break; 535 536 case 0x000b: 537 switch (op1) { 538 case 0x03: /* l.mulu */ 539 LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb); 540 if (rb != 0 && ra != 0) { 541 TCGv_i64 result = tcg_temp_local_new_i64(); 542 TCGv_i64 tra = tcg_temp_local_new_i64(); 543 TCGv_i64 trb = tcg_temp_local_new_i64(); 544 TCGv_i64 high = tcg_temp_new_i64(); 545 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 546 TCGLabel *lab = gen_new_label(); 547 /* Calculate each result. */ 548 tcg_gen_extu_i32_i64(tra, cpu_R[ra]); 549 tcg_gen_extu_i32_i64(trb, cpu_R[rb]); 550 tcg_gen_mul_i64(result, tra, trb); 551 tcg_temp_free_i64(tra); 552 tcg_temp_free_i64(trb); 553 tcg_gen_shri_i64(high, result, TARGET_LONG_BITS); 554 /* Overflow or not. */ 555 tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab); 556 tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 557 tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); 558 tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab); 559 gen_exception(dc, EXCP_RANGE); 560 gen_set_label(lab); 561 tcg_temp_free_i64(high); 562 tcg_gen_trunc_i64_tl(cpu_R[rd], result); 563 tcg_temp_free_i64(result); 564 tcg_temp_free_i32(sr_ove); 565 } else { 566 tcg_gen_movi_tl(cpu_R[rd], 0); 567 } 568 break; 569 570 default: 571 gen_illegal_exception(dc); 572 break; 573 } 574 break; 575 576 case 0x000e: 577 switch (op1) { 578 case 0x00: /* l.cmov */ 579 LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb); 580 { 581 TCGLabel *lab = gen_new_label(); 582 TCGv res = tcg_temp_local_new(); 583 TCGv sr_f = tcg_temp_new(); 584 tcg_gen_andi_tl(sr_f, cpu_sr, SR_F); 585 tcg_gen_mov_tl(res, cpu_R[rb]); 586 tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab); 587 tcg_gen_mov_tl(res, cpu_R[ra]); 588 gen_set_label(lab); 589 tcg_gen_mov_tl(cpu_R[rd], res); 590 tcg_temp_free(sr_f); 591 tcg_temp_free(res); 592 } 593 break; 594 595 default: 596 gen_illegal_exception(dc); 597 break; 598 } 599 break; 600 601 case 0x000f: 602 switch (op1) { 603 case 0x00: /* l.ff1 */ 604 LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb); 605 gen_helper_ff1(cpu_R[rd], cpu_R[ra]); 606 break; 607 case 0x01: /* l.fl1 */ 608 LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb); 609 gen_helper_fl1(cpu_R[rd], cpu_R[ra]); 610 break; 611 612 default: 613 gen_illegal_exception(dc); 614 break; 615 } 616 break; 617 618 case 0x0008: 619 switch (op1) { 620 case 0x00: 621 switch (op2) { 622 case 0x00: /* l.sll */ 623 LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb); 624 tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 625 break; 626 case 0x01: /* l.srl */ 627 LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb); 628 tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 629 break; 630 case 0x02: /* l.sra */ 631 LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb); 632 tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 633 break; 634 case 0x03: /* l.ror */ 635 LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb); 636 tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); 637 break; 638 639 default: 640 gen_illegal_exception(dc); 641 break; 642 } 643 break; 644 645 default: 646 gen_illegal_exception(dc); 647 break; 648 } 649 break; 650 651 case 0x000c: 652 switch (op1) { 653 case 0x00: 654 switch (op2) { 655 case 0x00: /* l.exths */ 656 LOG_DIS("l.exths r%d, r%d\n", rd, ra); 657 tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]); 658 break; 659 case 0x01: /* l.extbs */ 660 LOG_DIS("l.extbs r%d, r%d\n", rd, ra); 661 tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]); 662 break; 663 case 0x02: /* l.exthz */ 664 LOG_DIS("l.exthz r%d, r%d\n", rd, ra); 665 tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]); 666 break; 667 case 0x03: /* l.extbz */ 668 LOG_DIS("l.extbz r%d, r%d\n", rd, ra); 669 tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]); 670 break; 671 672 default: 673 gen_illegal_exception(dc); 674 break; 675 } 676 break; 677 678 default: 679 gen_illegal_exception(dc); 680 break; 681 } 682 break; 683 684 case 0x000d: 685 switch (op1) { 686 case 0x00: 687 switch (op2) { 688 case 0x00: /* l.extws */ 689 LOG_DIS("l.extws r%d, r%d\n", rd, ra); 690 tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]); 691 break; 692 case 0x01: /* l.extwz */ 693 LOG_DIS("l.extwz r%d, r%d\n", rd, ra); 694 tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]); 695 break; 696 697 default: 698 gen_illegal_exception(dc); 699 break; 700 } 701 break; 702 703 default: 704 gen_illegal_exception(dc); 705 break; 706 } 707 break; 708 709 default: 710 gen_illegal_exception(dc); 711 break; 712 } 713 } 714 715 static void dec_misc(DisasContext *dc, uint32_t insn) 716 { 717 uint32_t op0, op1; 718 uint32_t ra, rb, rd; 719 #ifdef OPENRISC_DISAS 720 uint32_t L6, K5; 721 #endif 722 uint32_t I16, I5, I11, N26, tmp; 723 TCGMemOp mop; 724 725 op0 = extract32(insn, 26, 6); 726 op1 = extract32(insn, 24, 2); 727 ra = extract32(insn, 16, 5); 728 rb = extract32(insn, 11, 5); 729 rd = extract32(insn, 21, 5); 730 #ifdef OPENRISC_DISAS 731 L6 = extract32(insn, 5, 6); 732 K5 = extract32(insn, 0, 5); 733 #endif 734 I16 = extract32(insn, 0, 16); 735 I5 = extract32(insn, 21, 5); 736 I11 = extract32(insn, 0, 11); 737 N26 = extract32(insn, 0, 26); 738 tmp = (I5<<11) + I11; 739 740 switch (op0) { 741 case 0x00: /* l.j */ 742 LOG_DIS("l.j %d\n", N26); 743 gen_jump(dc, N26, 0, op0); 744 break; 745 746 case 0x01: /* l.jal */ 747 LOG_DIS("l.jal %d\n", N26); 748 gen_jump(dc, N26, 0, op0); 749 break; 750 751 case 0x03: /* l.bnf */ 752 LOG_DIS("l.bnf %d\n", N26); 753 gen_jump(dc, N26, 0, op0); 754 break; 755 756 case 0x04: /* l.bf */ 757 LOG_DIS("l.bf %d\n", N26); 758 gen_jump(dc, N26, 0, op0); 759 break; 760 761 case 0x05: 762 switch (op1) { 763 case 0x01: /* l.nop */ 764 LOG_DIS("l.nop %d\n", I16); 765 break; 766 767 default: 768 gen_illegal_exception(dc); 769 break; 770 } 771 break; 772 773 case 0x11: /* l.jr */ 774 LOG_DIS("l.jr r%d\n", rb); 775 gen_jump(dc, 0, rb, op0); 776 break; 777 778 case 0x12: /* l.jalr */ 779 LOG_DIS("l.jalr r%d\n", rb); 780 gen_jump(dc, 0, rb, op0); 781 break; 782 783 case 0x13: /* l.maci */ 784 LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I11); 785 { 786 TCGv_i64 t1 = tcg_temp_new_i64(); 787 TCGv_i64 t2 = tcg_temp_new_i64(); 788 TCGv_i32 dst = tcg_temp_new_i32(); 789 TCGv ttmp = tcg_const_tl(tmp); 790 tcg_gen_mul_tl(dst, cpu_R[ra], ttmp); 791 tcg_gen_ext_i32_i64(t1, dst); 792 tcg_gen_concat_i32_i64(t2, maclo, machi); 793 tcg_gen_add_i64(t2, t2, t1); 794 tcg_gen_extrl_i64_i32(maclo, t2); 795 tcg_gen_shri_i64(t2, t2, 32); 796 tcg_gen_extrl_i64_i32(machi, t2); 797 tcg_temp_free_i32(dst); 798 tcg_temp_free(ttmp); 799 tcg_temp_free_i64(t1); 800 tcg_temp_free_i64(t2); 801 } 802 break; 803 804 case 0x09: /* l.rfe */ 805 LOG_DIS("l.rfe\n"); 806 { 807 #if defined(CONFIG_USER_ONLY) 808 return; 809 #else 810 if (dc->mem_idx == MMU_USER_IDX) { 811 gen_illegal_exception(dc); 812 return; 813 } 814 gen_helper_rfe(cpu_env); 815 dc->is_jmp = DISAS_UPDATE; 816 #endif 817 } 818 break; 819 820 case 0x1c: /* l.cust1 */ 821 LOG_DIS("l.cust1\n"); 822 break; 823 824 case 0x1d: /* l.cust2 */ 825 LOG_DIS("l.cust2\n"); 826 break; 827 828 case 0x1e: /* l.cust3 */ 829 LOG_DIS("l.cust3\n"); 830 break; 831 832 case 0x1f: /* l.cust4 */ 833 LOG_DIS("l.cust4\n"); 834 break; 835 836 case 0x3c: /* l.cust5 */ 837 LOG_DIS("l.cust5 r%d, r%d, r%d, %d, %d\n", rd, ra, rb, L6, K5); 838 break; 839 840 case 0x3d: /* l.cust6 */ 841 LOG_DIS("l.cust6\n"); 842 break; 843 844 case 0x3e: /* l.cust7 */ 845 LOG_DIS("l.cust7\n"); 846 break; 847 848 case 0x3f: /* l.cust8 */ 849 LOG_DIS("l.cust8\n"); 850 break; 851 852 /* not used yet, open it when we need or64. */ 853 /*#ifdef TARGET_OPENRISC64 854 case 0x20: l.ld 855 LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16); 856 check_ob64s(dc); 857 mop = MO_TEQ; 858 goto do_load; 859 #endif*/ 860 861 case 0x21: /* l.lwz */ 862 LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16); 863 mop = MO_TEUL; 864 goto do_load; 865 866 case 0x22: /* l.lws */ 867 LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16); 868 mop = MO_TESL; 869 goto do_load; 870 871 case 0x23: /* l.lbz */ 872 LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16); 873 mop = MO_UB; 874 goto do_load; 875 876 case 0x24: /* l.lbs */ 877 LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16); 878 mop = MO_SB; 879 goto do_load; 880 881 case 0x25: /* l.lhz */ 882 LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16); 883 mop = MO_TEUW; 884 goto do_load; 885 886 case 0x26: /* l.lhs */ 887 LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16); 888 mop = MO_TESW; 889 goto do_load; 890 891 do_load: 892 { 893 TCGv t0 = tcg_temp_new(); 894 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16)); 895 tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop); 896 tcg_temp_free(t0); 897 } 898 break; 899 900 case 0x27: /* l.addi */ 901 LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); 902 { 903 if (I16 == 0) { 904 tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]); 905 } else { 906 TCGLabel *lab = gen_new_label(); 907 TCGv_i64 ta = tcg_temp_new_i64(); 908 TCGv_i64 td = tcg_temp_local_new_i64(); 909 TCGv_i32 res = tcg_temp_local_new_i32(); 910 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 911 tcg_gen_extu_i32_i64(ta, cpu_R[ra]); 912 tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); 913 tcg_gen_extrl_i64_i32(res, td); 914 tcg_gen_shri_i64(td, td, 32); 915 tcg_gen_andi_i64(td, td, 0x3); 916 /* Jump to lab when no overflow. */ 917 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); 918 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); 919 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 920 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); 921 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); 922 gen_exception(dc, EXCP_RANGE); 923 gen_set_label(lab); 924 tcg_gen_mov_i32(cpu_R[rd], res); 925 tcg_temp_free_i64(ta); 926 tcg_temp_free_i64(td); 927 tcg_temp_free_i32(res); 928 tcg_temp_free_i32(sr_ove); 929 } 930 } 931 break; 932 933 case 0x28: /* l.addic */ 934 LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16); 935 { 936 TCGLabel *lab = gen_new_label(); 937 TCGv_i64 ta = tcg_temp_new_i64(); 938 TCGv_i64 td = tcg_temp_local_new_i64(); 939 TCGv_i64 tcy = tcg_temp_local_new_i64(); 940 TCGv_i32 res = tcg_temp_local_new_i32(); 941 TCGv_i32 sr_cy = tcg_temp_local_new_i32(); 942 TCGv_i32 sr_ove = tcg_temp_local_new_i32(); 943 tcg_gen_extu_i32_i64(ta, cpu_R[ra]); 944 tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY); 945 tcg_gen_shri_i32(sr_cy, sr_cy, 10); 946 tcg_gen_extu_i32_i64(tcy, sr_cy); 947 tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); 948 tcg_gen_add_i64(td, td, tcy); 949 tcg_gen_extrl_i64_i32(res, td); 950 tcg_gen_shri_i64(td, td, 32); 951 tcg_gen_andi_i64(td, td, 0x3); 952 /* Jump to lab when no overflow. */ 953 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); 954 tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); 955 tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); 956 tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); 957 tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); 958 gen_exception(dc, EXCP_RANGE); 959 gen_set_label(lab); 960 tcg_gen_mov_i32(cpu_R[rd], res); 961 tcg_temp_free_i64(ta); 962 tcg_temp_free_i64(td); 963 tcg_temp_free_i64(tcy); 964 tcg_temp_free_i32(res); 965 tcg_temp_free_i32(sr_cy); 966 tcg_temp_free_i32(sr_ove); 967 } 968 break; 969 970 case 0x29: /* l.andi */ 971 LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, I16); 972 tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16)); 973 break; 974 975 case 0x2a: /* l.ori */ 976 LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, I16); 977 tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16)); 978 break; 979 980 case 0x2b: /* l.xori */ 981 LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16); 982 tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], sign_extend(I16, 16)); 983 break; 984 985 case 0x2c: /* l.muli */ 986 LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16); 987 if (ra != 0 && I16 != 0) { 988 TCGv_i32 im = tcg_const_i32(I16); 989 gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], im); 990 tcg_temp_free_i32(im); 991 } else { 992 tcg_gen_movi_tl(cpu_R[rd], 0x0); 993 } 994 break; 995 996 case 0x2d: /* l.mfspr */ 997 LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16); 998 { 999 #if defined(CONFIG_USER_ONLY) 1000 return; 1001 #else 1002 TCGv_i32 ti = tcg_const_i32(I16); 1003 if (dc->mem_idx == MMU_USER_IDX) { 1004 gen_illegal_exception(dc); 1005 return; 1006 } 1007 gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti); 1008 tcg_temp_free_i32(ti); 1009 #endif 1010 } 1011 break; 1012 1013 case 0x30: /* l.mtspr */ 1014 LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11); 1015 { 1016 #if defined(CONFIG_USER_ONLY) 1017 return; 1018 #else 1019 TCGv_i32 im = tcg_const_i32(tmp); 1020 if (dc->mem_idx == MMU_USER_IDX) { 1021 gen_illegal_exception(dc); 1022 return; 1023 } 1024 gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im); 1025 tcg_temp_free_i32(im); 1026 #endif 1027 } 1028 break; 1029 1030 /* not used yet, open it when we need or64. */ 1031 /*#ifdef TARGET_OPENRISC64 1032 case 0x34: l.sd 1033 LOG_DIS("l.sd %d, r%d, r%d, %d\n", I5, ra, rb, I11); 1034 check_ob64s(dc); 1035 mop = MO_TEQ; 1036 goto do_store; 1037 #endif*/ 1038 1039 case 0x35: /* l.sw */ 1040 LOG_DIS("l.sw %d, r%d, r%d, %d\n", I5, ra, rb, I11); 1041 mop = MO_TEUL; 1042 goto do_store; 1043 1044 case 0x36: /* l.sb */ 1045 LOG_DIS("l.sb %d, r%d, r%d, %d\n", I5, ra, rb, I11); 1046 mop = MO_UB; 1047 goto do_store; 1048 1049 case 0x37: /* l.sh */ 1050 LOG_DIS("l.sh %d, r%d, r%d, %d\n", I5, ra, rb, I11); 1051 mop = MO_TEUW; 1052 goto do_store; 1053 1054 do_store: 1055 { 1056 TCGv t0 = tcg_temp_new(); 1057 tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16)); 1058 tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop); 1059 tcg_temp_free(t0); 1060 } 1061 break; 1062 1063 default: 1064 gen_illegal_exception(dc); 1065 break; 1066 } 1067 } 1068 1069 static void dec_mac(DisasContext *dc, uint32_t insn) 1070 { 1071 uint32_t op0; 1072 uint32_t ra, rb; 1073 op0 = extract32(insn, 0, 4); 1074 ra = extract32(insn, 16, 5); 1075 rb = extract32(insn, 11, 5); 1076 1077 switch (op0) { 1078 case 0x0001: /* l.mac */ 1079 LOG_DIS("l.mac r%d, r%d\n", ra, rb); 1080 { 1081 TCGv_i32 t0 = tcg_temp_new_i32(); 1082 TCGv_i64 t1 = tcg_temp_new_i64(); 1083 TCGv_i64 t2 = tcg_temp_new_i64(); 1084 tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]); 1085 tcg_gen_ext_i32_i64(t1, t0); 1086 tcg_gen_concat_i32_i64(t2, maclo, machi); 1087 tcg_gen_add_i64(t2, t2, t1); 1088 tcg_gen_extrl_i64_i32(maclo, t2); 1089 tcg_gen_shri_i64(t2, t2, 32); 1090 tcg_gen_extrl_i64_i32(machi, t2); 1091 tcg_temp_free_i32(t0); 1092 tcg_temp_free_i64(t1); 1093 tcg_temp_free_i64(t2); 1094 } 1095 break; 1096 1097 case 0x0002: /* l.msb */ 1098 LOG_DIS("l.msb r%d, r%d\n", ra, rb); 1099 { 1100 TCGv_i32 t0 = tcg_temp_new_i32(); 1101 TCGv_i64 t1 = tcg_temp_new_i64(); 1102 TCGv_i64 t2 = tcg_temp_new_i64(); 1103 tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]); 1104 tcg_gen_ext_i32_i64(t1, t0); 1105 tcg_gen_concat_i32_i64(t2, maclo, machi); 1106 tcg_gen_sub_i64(t2, t2, t1); 1107 tcg_gen_extrl_i64_i32(maclo, t2); 1108 tcg_gen_shri_i64(t2, t2, 32); 1109 tcg_gen_extrl_i64_i32(machi, t2); 1110 tcg_temp_free_i32(t0); 1111 tcg_temp_free_i64(t1); 1112 tcg_temp_free_i64(t2); 1113 } 1114 break; 1115 1116 default: 1117 gen_illegal_exception(dc); 1118 break; 1119 } 1120 } 1121 1122 static void dec_logic(DisasContext *dc, uint32_t insn) 1123 { 1124 uint32_t op0; 1125 uint32_t rd, ra, L6; 1126 op0 = extract32(insn, 6, 2); 1127 rd = extract32(insn, 21, 5); 1128 ra = extract32(insn, 16, 5); 1129 L6 = extract32(insn, 0, 6); 1130 1131 switch (op0) { 1132 case 0x00: /* l.slli */ 1133 LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6); 1134 tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); 1135 break; 1136 1137 case 0x01: /* l.srli */ 1138 LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6); 1139 tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); 1140 break; 1141 1142 case 0x02: /* l.srai */ 1143 LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6); 1144 tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); break; 1145 1146 case 0x03: /* l.rori */ 1147 LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6); 1148 tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); 1149 break; 1150 1151 default: 1152 gen_illegal_exception(dc); 1153 break; 1154 } 1155 } 1156 1157 static void dec_M(DisasContext *dc, uint32_t insn) 1158 { 1159 uint32_t op0; 1160 uint32_t rd; 1161 uint32_t K16; 1162 op0 = extract32(insn, 16, 1); 1163 rd = extract32(insn, 21, 5); 1164 K16 = extract32(insn, 0, 16); 1165 1166 switch (op0) { 1167 case 0x0: /* l.movhi */ 1168 LOG_DIS("l.movhi r%d, %d\n", rd, K16); 1169 tcg_gen_movi_tl(cpu_R[rd], (K16 << 16)); 1170 break; 1171 1172 case 0x1: /* l.macrc */ 1173 LOG_DIS("l.macrc r%d\n", rd); 1174 tcg_gen_mov_tl(cpu_R[rd], maclo); 1175 tcg_gen_movi_tl(maclo, 0x0); 1176 tcg_gen_movi_tl(machi, 0x0); 1177 break; 1178 1179 default: 1180 gen_illegal_exception(dc); 1181 break; 1182 } 1183 } 1184 1185 static void dec_comp(DisasContext *dc, uint32_t insn) 1186 { 1187 uint32_t op0; 1188 uint32_t ra, rb; 1189 1190 op0 = extract32(insn, 21, 5); 1191 ra = extract32(insn, 16, 5); 1192 rb = extract32(insn, 11, 5); 1193 1194 tcg_gen_movi_i32(env_btaken, 0x0); 1195 /* unsigned integers */ 1196 tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]); 1197 tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]); 1198 1199 switch (op0) { 1200 case 0x0: /* l.sfeq */ 1201 LOG_DIS("l.sfeq r%d, r%d\n", ra, rb); 1202 tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]); 1203 break; 1204 1205 case 0x1: /* l.sfne */ 1206 LOG_DIS("l.sfne r%d, r%d\n", ra, rb); 1207 tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]); 1208 break; 1209 1210 case 0x2: /* l.sfgtu */ 1211 LOG_DIS("l.sfgtu r%d, r%d\n", ra, rb); 1212 tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]); 1213 break; 1214 1215 case 0x3: /* l.sfgeu */ 1216 LOG_DIS("l.sfgeu r%d, r%d\n", ra, rb); 1217 tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]); 1218 break; 1219 1220 case 0x4: /* l.sfltu */ 1221 LOG_DIS("l.sfltu r%d, r%d\n", ra, rb); 1222 tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]); 1223 break; 1224 1225 case 0x5: /* l.sfleu */ 1226 LOG_DIS("l.sfleu r%d, r%d\n", ra, rb); 1227 tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]); 1228 break; 1229 1230 case 0xa: /* l.sfgts */ 1231 LOG_DIS("l.sfgts r%d, r%d\n", ra, rb); 1232 tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]); 1233 break; 1234 1235 case 0xb: /* l.sfges */ 1236 LOG_DIS("l.sfges r%d, r%d\n", ra, rb); 1237 tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]); 1238 break; 1239 1240 case 0xc: /* l.sflts */ 1241 LOG_DIS("l.sflts r%d, r%d\n", ra, rb); 1242 tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]); 1243 break; 1244 1245 case 0xd: /* l.sfles */ 1246 LOG_DIS("l.sfles r%d, r%d\n", ra, rb); 1247 tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]); 1248 break; 1249 1250 default: 1251 gen_illegal_exception(dc); 1252 break; 1253 } 1254 wb_SR_F(); 1255 } 1256 1257 static void dec_compi(DisasContext *dc, uint32_t insn) 1258 { 1259 uint32_t op0; 1260 uint32_t ra, I16; 1261 1262 op0 = extract32(insn, 21, 5); 1263 ra = extract32(insn, 16, 5); 1264 I16 = extract32(insn, 0, 16); 1265 1266 tcg_gen_movi_i32(env_btaken, 0x0); 1267 I16 = sign_extend(I16, 16); 1268 1269 switch (op0) { 1270 case 0x0: /* l.sfeqi */ 1271 LOG_DIS("l.sfeqi r%d, %d\n", ra, I16); 1272 tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16); 1273 break; 1274 1275 case 0x1: /* l.sfnei */ 1276 LOG_DIS("l.sfnei r%d, %d\n", ra, I16); 1277 tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16); 1278 break; 1279 1280 case 0x2: /* l.sfgtui */ 1281 LOG_DIS("l.sfgtui r%d, %d\n", ra, I16); 1282 tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16); 1283 break; 1284 1285 case 0x3: /* l.sfgeui */ 1286 LOG_DIS("l.sfgeui r%d, %d\n", ra, I16); 1287 tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16); 1288 break; 1289 1290 case 0x4: /* l.sfltui */ 1291 LOG_DIS("l.sfltui r%d, %d\n", ra, I16); 1292 tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16); 1293 break; 1294 1295 case 0x5: /* l.sfleui */ 1296 LOG_DIS("l.sfleui r%d, %d\n", ra, I16); 1297 tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16); 1298 break; 1299 1300 case 0xa: /* l.sfgtsi */ 1301 LOG_DIS("l.sfgtsi r%d, %d\n", ra, I16); 1302 tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16); 1303 break; 1304 1305 case 0xb: /* l.sfgesi */ 1306 LOG_DIS("l.sfgesi r%d, %d\n", ra, I16); 1307 tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16); 1308 break; 1309 1310 case 0xc: /* l.sfltsi */ 1311 LOG_DIS("l.sfltsi r%d, %d\n", ra, I16); 1312 tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16); 1313 break; 1314 1315 case 0xd: /* l.sflesi */ 1316 LOG_DIS("l.sflesi r%d, %d\n", ra, I16); 1317 tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16); 1318 break; 1319 1320 default: 1321 gen_illegal_exception(dc); 1322 break; 1323 } 1324 wb_SR_F(); 1325 } 1326 1327 static void dec_sys(DisasContext *dc, uint32_t insn) 1328 { 1329 uint32_t op0; 1330 #ifdef OPENRISC_DISAS 1331 uint32_t K16; 1332 #endif 1333 op0 = extract32(insn, 16, 10); 1334 #ifdef OPENRISC_DISAS 1335 K16 = extract32(insn, 0, 16); 1336 #endif 1337 1338 switch (op0) { 1339 case 0x000: /* l.sys */ 1340 LOG_DIS("l.sys %d\n", K16); 1341 tcg_gen_movi_tl(cpu_pc, dc->pc); 1342 gen_exception(dc, EXCP_SYSCALL); 1343 dc->is_jmp = DISAS_UPDATE; 1344 break; 1345 1346 case 0x100: /* l.trap */ 1347 LOG_DIS("l.trap %d\n", K16); 1348 #if defined(CONFIG_USER_ONLY) 1349 return; 1350 #else 1351 if (dc->mem_idx == MMU_USER_IDX) { 1352 gen_illegal_exception(dc); 1353 return; 1354 } 1355 tcg_gen_movi_tl(cpu_pc, dc->pc); 1356 gen_exception(dc, EXCP_TRAP); 1357 #endif 1358 break; 1359 1360 case 0x300: /* l.csync */ 1361 LOG_DIS("l.csync\n"); 1362 #if defined(CONFIG_USER_ONLY) 1363 return; 1364 #else 1365 if (dc->mem_idx == MMU_USER_IDX) { 1366 gen_illegal_exception(dc); 1367 return; 1368 } 1369 #endif 1370 break; 1371 1372 case 0x200: /* l.msync */ 1373 LOG_DIS("l.msync\n"); 1374 #if defined(CONFIG_USER_ONLY) 1375 return; 1376 #else 1377 if (dc->mem_idx == MMU_USER_IDX) { 1378 gen_illegal_exception(dc); 1379 return; 1380 } 1381 #endif 1382 break; 1383 1384 case 0x270: /* l.psync */ 1385 LOG_DIS("l.psync\n"); 1386 #if defined(CONFIG_USER_ONLY) 1387 return; 1388 #else 1389 if (dc->mem_idx == MMU_USER_IDX) { 1390 gen_illegal_exception(dc); 1391 return; 1392 } 1393 #endif 1394 break; 1395 1396 default: 1397 gen_illegal_exception(dc); 1398 break; 1399 } 1400 } 1401 1402 static void dec_float(DisasContext *dc, uint32_t insn) 1403 { 1404 uint32_t op0; 1405 uint32_t ra, rb, rd; 1406 op0 = extract32(insn, 0, 8); 1407 ra = extract32(insn, 16, 5); 1408 rb = extract32(insn, 11, 5); 1409 rd = extract32(insn, 21, 5); 1410 1411 switch (op0) { 1412 case 0x00: /* lf.add.s */ 1413 LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb); 1414 gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1415 break; 1416 1417 case 0x01: /* lf.sub.s */ 1418 LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb); 1419 gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1420 break; 1421 1422 1423 case 0x02: /* lf.mul.s */ 1424 LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb); 1425 if (ra != 0 && rb != 0) { 1426 gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1427 } else { 1428 tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF); 1429 tcg_gen_movi_i32(cpu_R[rd], 0x0); 1430 } 1431 break; 1432 1433 case 0x03: /* lf.div.s */ 1434 LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb); 1435 gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1436 break; 1437 1438 case 0x04: /* lf.itof.s */ 1439 LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1440 gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]); 1441 break; 1442 1443 case 0x05: /* lf.ftoi.s */ 1444 LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1445 gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]); 1446 break; 1447 1448 case 0x06: /* lf.rem.s */ 1449 LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb); 1450 gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1451 break; 1452 1453 case 0x07: /* lf.madd.s */ 1454 LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb); 1455 gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1456 break; 1457 1458 case 0x08: /* lf.sfeq.s */ 1459 LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb); 1460 gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1461 break; 1462 1463 case 0x09: /* lf.sfne.s */ 1464 LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb); 1465 gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1466 break; 1467 1468 case 0x0a: /* lf.sfgt.s */ 1469 LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb); 1470 gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1471 break; 1472 1473 case 0x0b: /* lf.sfge.s */ 1474 LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb); 1475 gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1476 break; 1477 1478 case 0x0c: /* lf.sflt.s */ 1479 LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb); 1480 gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1481 break; 1482 1483 case 0x0d: /* lf.sfle.s */ 1484 LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb); 1485 gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1486 break; 1487 1488 /* not used yet, open it when we need or64. */ 1489 /*#ifdef TARGET_OPENRISC64 1490 case 0x10: lf.add.d 1491 LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb); 1492 check_of64s(dc); 1493 gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1494 break; 1495 1496 case 0x11: lf.sub.d 1497 LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb); 1498 check_of64s(dc); 1499 gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1500 break; 1501 1502 case 0x12: lf.mul.d 1503 LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb); 1504 check_of64s(dc); 1505 if (ra != 0 && rb != 0) { 1506 gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1507 } else { 1508 tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF); 1509 tcg_gen_movi_i64(cpu_R[rd], 0x0); 1510 } 1511 break; 1512 1513 case 0x13: lf.div.d 1514 LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb); 1515 check_of64s(dc); 1516 gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1517 break; 1518 1519 case 0x14: lf.itof.d 1520 LOG_DIS("lf.itof r%d, r%d\n", rd, ra); 1521 check_of64s(dc); 1522 gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]); 1523 break; 1524 1525 case 0x15: lf.ftoi.d 1526 LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra); 1527 check_of64s(dc); 1528 gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]); 1529 break; 1530 1531 case 0x16: lf.rem.d 1532 LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb); 1533 check_of64s(dc); 1534 gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1535 break; 1536 1537 case 0x17: lf.madd.d 1538 LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb); 1539 check_of64s(dc); 1540 gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); 1541 break; 1542 1543 case 0x18: lf.sfeq.d 1544 LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb); 1545 check_of64s(dc); 1546 gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1547 break; 1548 1549 case 0x1a: lf.sfgt.d 1550 LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb); 1551 check_of64s(dc); 1552 gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1553 break; 1554 1555 case 0x1b: lf.sfge.d 1556 LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb); 1557 check_of64s(dc); 1558 gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1559 break; 1560 1561 case 0x19: lf.sfne.d 1562 LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb); 1563 check_of64s(dc); 1564 gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1565 break; 1566 1567 case 0x1c: lf.sflt.d 1568 LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb); 1569 check_of64s(dc); 1570 gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1571 break; 1572 1573 case 0x1d: lf.sfle.d 1574 LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb); 1575 check_of64s(dc); 1576 gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]); 1577 break; 1578 #endif*/ 1579 1580 default: 1581 gen_illegal_exception(dc); 1582 break; 1583 } 1584 wb_SR_F(); 1585 } 1586 1587 static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu) 1588 { 1589 uint32_t op0; 1590 uint32_t insn; 1591 insn = cpu_ldl_code(&cpu->env, dc->pc); 1592 op0 = extract32(insn, 26, 6); 1593 1594 switch (op0) { 1595 case 0x06: 1596 dec_M(dc, insn); 1597 break; 1598 1599 case 0x08: 1600 dec_sys(dc, insn); 1601 break; 1602 1603 case 0x2e: 1604 dec_logic(dc, insn); 1605 break; 1606 1607 case 0x2f: 1608 dec_compi(dc, insn); 1609 break; 1610 1611 case 0x31: 1612 dec_mac(dc, insn); 1613 break; 1614 1615 case 0x32: 1616 dec_float(dc, insn); 1617 break; 1618 1619 case 0x38: 1620 dec_calc(dc, insn); 1621 break; 1622 1623 case 0x39: 1624 dec_comp(dc, insn); 1625 break; 1626 1627 default: 1628 dec_misc(dc, insn); 1629 break; 1630 } 1631 } 1632 1633 void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) 1634 { 1635 OpenRISCCPU *cpu = openrisc_env_get_cpu(env); 1636 CPUState *cs = CPU(cpu); 1637 struct DisasContext ctx, *dc = &ctx; 1638 uint32_t pc_start; 1639 uint32_t next_page_start; 1640 int num_insns; 1641 int max_insns; 1642 1643 pc_start = tb->pc; 1644 dc->tb = tb; 1645 1646 dc->is_jmp = DISAS_NEXT; 1647 dc->ppc = pc_start; 1648 dc->pc = pc_start; 1649 dc->flags = cpu->env.cpucfgr; 1650 dc->mem_idx = cpu_mmu_index(&cpu->env, false); 1651 dc->synced_flags = dc->tb_flags = tb->flags; 1652 dc->delayed_branch = !!(dc->tb_flags & D_FLAG); 1653 dc->singlestep_enabled = cs->singlestep_enabled; 1654 1655 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; 1656 num_insns = 0; 1657 max_insns = tb->cflags & CF_COUNT_MASK; 1658 1659 if (max_insns == 0) { 1660 max_insns = CF_COUNT_MASK; 1661 } 1662 if (max_insns > TCG_MAX_INSNS) { 1663 max_insns = TCG_MAX_INSNS; 1664 } 1665 1666 gen_tb_start(tb); 1667 1668 do { 1669 tcg_gen_insn_start(dc->pc); 1670 num_insns++; 1671 1672 if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { 1673 tcg_gen_movi_tl(cpu_pc, dc->pc); 1674 gen_exception(dc, EXCP_DEBUG); 1675 dc->is_jmp = DISAS_UPDATE; 1676 /* The address covered by the breakpoint must be included in 1677 [tb->pc, tb->pc + tb->size) in order to for it to be 1678 properly cleared -- thus we increment the PC here so that 1679 the logic setting tb->size below does the right thing. */ 1680 dc->pc += 4; 1681 break; 1682 } 1683 1684 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { 1685 gen_io_start(); 1686 } 1687 dc->ppc = dc->pc - 4; 1688 dc->npc = dc->pc + 4; 1689 tcg_gen_movi_tl(cpu_ppc, dc->ppc); 1690 tcg_gen_movi_tl(cpu_npc, dc->npc); 1691 disas_openrisc_insn(dc, cpu); 1692 dc->pc = dc->npc; 1693 /* delay slot */ 1694 if (dc->delayed_branch) { 1695 dc->delayed_branch--; 1696 if (!dc->delayed_branch) { 1697 dc->tb_flags &= ~D_FLAG; 1698 gen_sync_flags(dc); 1699 tcg_gen_mov_tl(cpu_pc, jmp_pc); 1700 tcg_gen_mov_tl(cpu_npc, jmp_pc); 1701 tcg_gen_movi_tl(jmp_pc, 0); 1702 tcg_gen_exit_tb(0); 1703 dc->is_jmp = DISAS_JUMP; 1704 break; 1705 } 1706 } 1707 } while (!dc->is_jmp 1708 && !tcg_op_buf_full() 1709 && !cs->singlestep_enabled 1710 && !singlestep 1711 && (dc->pc < next_page_start) 1712 && num_insns < max_insns); 1713 1714 if (tb->cflags & CF_LAST_IO) { 1715 gen_io_end(); 1716 } 1717 if (dc->is_jmp == DISAS_NEXT) { 1718 dc->is_jmp = DISAS_UPDATE; 1719 tcg_gen_movi_tl(cpu_pc, dc->pc); 1720 } 1721 if (unlikely(cs->singlestep_enabled)) { 1722 if (dc->is_jmp == DISAS_NEXT) { 1723 tcg_gen_movi_tl(cpu_pc, dc->pc); 1724 } 1725 gen_exception(dc, EXCP_DEBUG); 1726 } else { 1727 switch (dc->is_jmp) { 1728 case DISAS_NEXT: 1729 gen_goto_tb(dc, 0, dc->pc); 1730 break; 1731 default: 1732 case DISAS_JUMP: 1733 break; 1734 case DISAS_UPDATE: 1735 /* indicate that the hash table must be used 1736 to find the next TB */ 1737 tcg_gen_exit_tb(0); 1738 break; 1739 case DISAS_TB_JUMP: 1740 /* nothing more to generate */ 1741 break; 1742 } 1743 } 1744 1745 gen_tb_end(tb, num_insns); 1746 1747 tb->size = dc->pc - pc_start; 1748 tb->icount = num_insns; 1749 1750 #ifdef DEBUG_DISAS 1751 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) 1752 && qemu_log_in_addr_range(pc_start)) { 1753 qemu_log_lock(); 1754 qemu_log("----------------\n"); 1755 qemu_log("IN: %s\n", lookup_symbol(pc_start)); 1756 log_target_disas(cs, pc_start, dc->pc - pc_start, 0); 1757 qemu_log("\nisize=%d osize=%d\n", 1758 dc->pc - pc_start, tcg_op_buf_count()); 1759 qemu_log_unlock(); 1760 } 1761 #endif 1762 } 1763 1764 void openrisc_cpu_dump_state(CPUState *cs, FILE *f, 1765 fprintf_function cpu_fprintf, 1766 int flags) 1767 { 1768 OpenRISCCPU *cpu = OPENRISC_CPU(cs); 1769 CPUOpenRISCState *env = &cpu->env; 1770 int i; 1771 1772 cpu_fprintf(f, "PC=%08x\n", env->pc); 1773 for (i = 0; i < 32; ++i) { 1774 cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i], 1775 (i % 4) == 3 ? '\n' : ' '); 1776 } 1777 } 1778 1779 void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, 1780 target_ulong *data) 1781 { 1782 env->pc = data[0]; 1783 } 1784