URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [tags/] [nog_patch_60/] [or1ksim/] [cpu/] [or32/] [insnset.c] - Rev 722
Go to most recent revision | Compare with Previous | Blame | View Log
/* execute.c -- Instruction specific functions. Copyright (C) 1999 Damjan Lampret, lampret@opencores.org 2000-2002 Marko Mlinar, markom@opencores.org This file is part of OpenRISC 1000 Architectural Simulator. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ INSTRUCTION (l_add) { signed long temp1; signed char temp4; IFF (config.cpu.dependstats) current->func_unit = it_arith; temp1 = (signed long)eval_operand32(2, &breakpoint)+(signed long)eval_operand32(1, &breakpoint); set_operand32(0, temp1, &breakpoint); set_ov_flag (temp1); if (ARITH_SET_FLAG) { flag = temp1 == 0; setsprbits(SPR_SR, SPR_SR_F, flag); } temp4 = temp1; if (temp4 == temp1) mstats.byteadd++; } INSTRUCTION (l_sw) { int old_cyc = 0; IFF (config.cpu.dependstats) current->func_unit = it_store; IFF (config.cpu.sbuf_len) old_cyc = mem_cycles; set_operand32(0, eval_operand32(1, &breakpoint), &breakpoint); if (config.cpu.sbuf_len) { int t = mem_cycles; mem_cycles = old_cyc; sbuf_store (t - old_cyc); } } INSTRUCTION (l_sb) { int old_cyc = 0; IFF (config.cpu.dependstats) current->func_unit = it_store; IFF (config.cpu.sbuf_len) old_cyc = mem_cycles; set_operand8(0, eval_operand32(1, &breakpoint), &breakpoint); if (config.cpu.sbuf_len) { int t = mem_cycles; mem_cycles = old_cyc; sbuf_store (t- old_cyc); } } INSTRUCTION (l_sh) { int old_cyc = 0; IFF (config.cpu.dependstats) current->func_unit = it_store; IFF (config.cpu.sbuf_len) old_cyc = mem_cycles; set_operand16(0, eval_operand32(1, &breakpoint), &breakpoint); if (config.cpu.sbuf_len) { int t = mem_cycles; mem_cycles = old_cyc; sbuf_store (t - old_cyc); } } INSTRUCTION (l_lwz) { unsigned long val; IFF (config.cpu.dependstats) current->func_unit = it_load; if (config.cpu.sbuf_len) sbuf_load (); val = eval_operand32(1, &breakpoint); /* If eval operand produced exception don't set anything */ if (!pending.valid) set_operand32(0, val, &breakpoint); } INSTRUCTION (l_lbs) { signed char val; IFF (config.cpu.dependstats) current->func_unit = it_load; if (config.cpu.sbuf_len) sbuf_load (); val = eval_operand8(1, &breakpoint); /* If eval opreand produced exception don't set anything */ if (!pending.valid) set_operand32(0, val, &breakpoint); } INSTRUCTION (l_lbz) { unsigned char val; IFF (config.cpu.dependstats) current->func_unit = it_load; if (config.cpu.sbuf_len) sbuf_load (); val = eval_operand8(1, &breakpoint); /* If eval opreand produced exception don't set anything */ if (!pending.valid) set_operand32(0, val, &breakpoint); } INSTRUCTION (l_lhs) { signed short val; IFF (config.cpu.dependstats) current->func_unit = it_load; if (config.cpu.sbuf_len) sbuf_load (); val = eval_operand16(1, &breakpoint); /* If eval opreand produced exception don't set anything */ if (!pending.valid) set_operand32(0, val, &breakpoint); } INSTRUCTION (l_lhz) { unsigned short val; IFF (config.cpu.dependstats) current->func_unit = it_load; if (config.cpu.sbuf_len) sbuf_load (); val = eval_operand16(1, &breakpoint); /* If eval opreand produced exception don't set anything */ if (!pending.valid) set_operand32(0, val, &breakpoint); } INSTRUCTION (l_movhi) { IFF (config.cpu.dependstats) current->func_unit = it_movimm; set_operand32(0, eval_operand32(1, &breakpoint) << 16, &breakpoint); } INSTRUCTION (l_and) { unsigned long temp1; IFF (config.cpu.dependstats) current->func_unit = it_arith; set_operand32(0, temp1 = set_ov_flag (eval_operand32(1, &breakpoint) & (unsigned)eval_operand32(2, &breakpoint)), &breakpoint); if (ARITH_SET_FLAG) { flag = temp1 == 0; setsprbits(SPR_SR, SPR_SR_F, flag); } } INSTRUCTION (l_or) { IFF (config.cpu.dependstats) current->func_unit = it_arith; set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) | (unsigned)eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (l_xor) { IFF (config.cpu.dependstats) current->func_unit = it_arith; set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) ^ (signed)eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (l_sub) { IFF (config.cpu.dependstats) current->func_unit = it_arith; set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) - (signed long)eval_operand32(2, &breakpoint)), &breakpoint); } /*int mcount = 0;*/ INSTRUCTION (l_mul) { signed long temp3, temp2, temp1; IFF (config.cpu.dependstats) current->func_unit = it_arith; set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) * (signed long)eval_operand32(2, &breakpoint)), &breakpoint); /*if (!(mcount++ & 1023)) { printf ("[%i]\n",mcount); }*/ } INSTRUCTION (l_div) { signed long temp3, temp2, temp1; IFF (config.cpu.dependstats) current->func_unit = it_arith; temp3 = eval_operand32(2, &breakpoint); temp2 = eval_operand32(1, &breakpoint); if (temp3) temp1 = temp2 / temp3; else { except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr); return; } set_operand32(0, set_ov_flag (temp1), &breakpoint); } INSTRUCTION (l_divu) { unsigned long temp3, temp2, temp1; IFF (config.cpu.dependstats) current->func_unit = it_arith; temp3 = eval_operand32(2, &breakpoint); temp2 = eval_operand32(1, &breakpoint); temp1 = temp2 / temp3; /* cycles += 16; */ set_operand32(0, set_ov_flag (temp1), &breakpoint); } INSTRUCTION (l_sll) { int sign = 1; IFF (config.cpu.dependstats) current->func_unit = it_shift; if ((signed)eval_operand32(1, &breakpoint) < 0) sign = -1; /* cycles += 2; */ set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) << eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (l_sra) { unsigned long sign = 0; IFF (config.cpu.dependstats) current->func_unit = it_shift; if ((signed)eval_operand32(1, &breakpoint) < 0) sign = -1; /* cycles += 2; */ set_operand32(0, set_ov_flag ((signed)eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (l_srl) { IFF (config.cpu.dependstats) current->func_unit = it_shift; /* cycles += 2; */ set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (l_bf) { if (config.bpb.enabled) { int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0; IFF (config.cpu.dependstats) current->func_unit = it_branch; mstats.bf[flag][fwd]++; bpb_update(current->insn_addr, flag); } if (flag) { pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; btic_update(pcnext); next_delay_insn = 1; } else { btic_update(pc); } } INSTRUCTION (l_bnf) { if (config.bpb.enabled) { int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0; IFF (config.cpu.dependstats) current->func_unit = it_branch; mstats.bnf[!flag][fwd]++; bpb_update(current->insn_addr, flag == 0); } if (flag == 0) { pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; btic_update(pcnext); next_delay_insn = 1; } else { btic_update(pc); } } INSTRUCTION (l_j) { pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; IFF (config.cpu.dependstats) current->func_unit = it_jump; next_delay_insn = 1; } INSTRUCTION (l_jal) { pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; IFF (config.cpu.dependstats) current->func_unit = it_jump; set_reg32(LINK_REGNO, pc + 8); next_delay_insn = 1; if (config.sim.profile) { struct mem_entry *entry; struct label_entry *tmp; if (verify_memoryarea(pcdelay) && (tmp = get_label (pcdelay))) fprintf (runtime.sim.fprof, "+%08X %08X %08X %s\n", cycles, pc + 8, pcdelay, tmp->name); else fprintf (runtime.sim.fprof, "+%08X %08X %08X @%08X\n", cycles, pc + 8, pcdelay, pcdelay); } } INSTRUCTION (l_jalr) { IFF (config.cpu.dependstats) current->func_unit = it_jump; pcdelay = eval_operand32(0, &breakpoint); set_reg32(LINK_REGNO, pc + 8); next_delay_insn = 1; } INSTRUCTION (l_jr) { IFF (config.cpu.dependstats) current->func_unit = it_jump; pcdelay = eval_operand32(0, &breakpoint); next_delay_insn = 1; if (config.sim.profile) fprintf (runtime.sim.fprof, "-%08X %08X\n", cycles, pcdelay); } INSTRUCTION (l_rfe) { IFF (config.cpu.dependstats) current->func_unit = it_exception; pcnext = mfspr(SPR_EPCR_BASE); mtspr(SPR_SR, mfspr(SPR_ESR_BASE)); } INSTRUCTION (l_nop) { unsigned long stackaddr; int k = eval_operand32(0, &breakpoint); IFF (config.cpu.dependstats) current->func_unit = it_nop; switch (k) { case NOP_NOP: break; case NOP_EXIT: printf("exit(%d)\n", evalsim_reg32 (3)); if (config.debug.gdb_enabled) set_stall_state (1); else cont_run = 0; break; case NOP_PRINTF: stackaddr = evalsim_reg32(4); simprintf(stackaddr, evalsim_reg32(3)); debug(5, "simprintf %x\n", stackaddr); break; case NOP_REPORT: printf("report(0x%x);\n", evalsim_reg32(3)); default: if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST) printf("report %i (0x%x);\n", k - NOP_REPORT_FIRST, evalsim_reg32(3)); break; } } INSTRUCTION (l_sfeq) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = eval_operand32(0, &breakpoint) == eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfne) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = eval_operand32(0, &breakpoint) != eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfgts) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (signed)eval_operand32(0, &breakpoint) > (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfges) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (signed)eval_operand32(0, &breakpoint) >= (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sflts) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (signed)eval_operand32(0, &breakpoint) < (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfles) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (signed)eval_operand32(0, &breakpoint) <= (signed)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfgtu) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (unsigned)eval_operand32(0, &breakpoint) > (unsigned)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfgeu) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (unsigned)eval_operand32(0, &breakpoint) >= (unsigned) eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfltu) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (unsigned)eval_operand32(0, &breakpoint) < (unsigned)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_sfleu) { IFF (config.cpu.dependstats) current->func_unit = it_compare; flag = (unsigned)eval_operand32(0, &breakpoint) <= (unsigned)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (l_extbs) { unsigned char x; IFF (config.cpu.dependstats) current->func_unit = it_move; x = eval_operand32(1, &breakpoint); set_operand32(0, (signed long)x, &breakpoint); } INSTRUCTION (l_extbz) { unsigned char x; IFF (config.cpu.dependstats) current->func_unit = it_move; x = eval_operand32(1, &breakpoint); set_operand32(0, (unsigned long)x, &breakpoint); } INSTRUCTION (l_exths) { unsigned short x; IFF (config.cpu.dependstats) current->func_unit = it_move; x = eval_operand32(1, &breakpoint); set_operand32(0, (signed long)x, &breakpoint); } INSTRUCTION (l_exthz) { unsigned short x; IFF (config.cpu.dependstats) current->func_unit = it_move; x = eval_operand32(1, &breakpoint); set_operand32(0, (unsigned long)x, &breakpoint); } INSTRUCTION (l_extws) { unsigned int x; IFF (config.cpu.dependstats) current->func_unit = it_move; x = eval_operand32(1, &breakpoint); set_operand32(0, (signed long)x, &breakpoint); } INSTRUCTION (l_extwz) { unsigned int x; IFF (config.cpu.dependstats) current->func_unit = it_move; x = eval_operand32(1, &breakpoint); set_operand32(0, (unsigned long)x, &breakpoint); } INSTRUCTION (l_mtspr) { unsigned long regno = eval_operand32(0, &breakpoint) + eval_operand32(2, &breakpoint); unsigned long value = eval_operand32(1, &breakpoint); if (runtime.sim.fspr_log) { fprintf(runtime.sim.fspr_log, "Write to SPR : [%08lX] <- [%08lX]\n", regno, value); } IFF (config.cpu.dependstats) current->func_unit = it_move; if (mfspr(SPR_SR) & SPR_SR_SM) mtspr(regno, value); else { printf("WARNING: trying to write SPR while SR[SUPV] is cleared.\n"); cont_run = 0; } } INSTRUCTION (l_mfspr) { unsigned long regno = eval_operand32(1, &breakpoint) + eval_operand32(2, &breakpoint); unsigned long value = mfspr(regno); if (runtime.sim.fspr_log) { fprintf(runtime.sim.fspr_log, "Read from SPR : [%08lX] -> [%08lX]\n", regno, value); } IFF (config.cpu.dependstats) current->func_unit = it_move; if (mfspr(SPR_SR) & SPR_SR_SM) set_operand32(0, value, &breakpoint); else { set_operand32(0, 0, &breakpoint); printf("WARNING: trying to read SPR while SR[SUPV] is cleared.\n"); cont_run = 0; } } INSTRUCTION (l_sys) { except_handle(EXCEPT_SYSCALL, mfspr(SPR_EEAR_BASE)); } INSTRUCTION (l_trap) { /* TODO: some SR related code here! */ except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE)); } INSTRUCTION (l_mac) { sprword lo, hi; LONGEST l; long x, y; IFF (config.cpu.dependstats) current->func_unit = it_mac; lo = mfspr (SPR_MACLO); hi = mfspr (SPR_MACHI); x = eval_operand32(0, &breakpoint); y = eval_operand32(1, &breakpoint); printf ("[%08x,%08x]\t", (unsigned long)(x), (unsigned long)(y)); l = (ULONGEST)lo | ((LONGEST)hi << 32); l += (LONGEST) x * (LONGEST) y; /* This implementation is very fast - it needs only one cycle for mac. */ lo = ((ULONGEST)l) & 0xFFFFFFFF; hi = ((LONGEST)l) >> 32; mtspr (SPR_MACLO, lo); mtspr (SPR_MACHI, hi); printf ("(%08x,%08x)\n", hi, lo); } INSTRUCTION (l_msb) { sprword lo, hi; LONGEST l; long x, y; IFF (config.cpu.dependstats) current->func_unit = it_mac; lo = mfspr (SPR_MACLO); hi = mfspr (SPR_MACHI); x = eval_operand32(0, &breakpoint); y = eval_operand32(1, &breakpoint); printf ("[%08x,%08x]\t", (unsigned long)(x), (unsigned long)(y)); l = (ULONGEST)lo | ((LONGEST)hi << 32); l -= (LONGEST) eval_operand32(0, &breakpoint) * (LONGEST)eval_operand32(1, &breakpoint); /* This implementation is very fast - it needs only one cycle for msb. */ lo = ((ULONGEST)l) & 0xFFFFFFFF; hi = ((LONGEST)l) >> 32; mtspr (SPR_MACLO, lo); mtspr (SPR_MACHI, hi); printf ("(%08x,%08x)\n", hi, lo); } INSTRUCTION (l_macrc) { sprword lo, hi; LONGEST l; IFF (config.cpu.dependstats) current->func_unit = it_mac; /* No need for synchronization here -- all MAC instructions are 1 cycle long. */ lo = mfspr (SPR_MACLO); hi = mfspr (SPR_MACHI); l = (ULONGEST) lo | ((LONGEST)hi << 32); l >>= 28; //printf ("<%08x>\n", (unsigned long)l); set_operand32(0, (long)l, &breakpoint); mtspr (SPR_MACLO, 0); mtspr (SPR_MACHI, 0); } INSTRUCTION (l_cmov) { IFF (config.cpu.dependstats) current->func_unit = it_move; set_operand32(0, flag ? eval_operand32(1, &breakpoint) : eval_operand32(2, &breakpoint), &breakpoint); } /******* Floating point instructions *******/ /* Single precision */ INSTRUCTION (lf_add_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; set_operand32(0, (machword)((float)eval_operand32(1, &breakpoint) + (float)eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (lf_div_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; set_operand32(0, (machword)((float)eval_operand32(1, &breakpoint) / (float)eval_operand32(2, &breakpoint)), &breakpoint); } /*INSTRUCTION (lf_ftoi_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; set_operand32(0, freg[get_operand(1)], &breakpoint); } INSTRUCTION (lf_itof_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; freg[get_operand(0)] = eval_operand32(1, &breakpoint); }*/ INSTRUCTION (lf_madd_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; set_operand32(0, (machword)((float)eval_operand32(0, &breakpoint) + (float)eval_operand32(1, &breakpoint) * (float)eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (lf_mul_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; set_operand32(0, (machword)((float)eval_operand32(1, &breakpoint) * (float)eval_operand32(2, &breakpoint)), &breakpoint); } INSTRUCTION (lf_rem_s) { float temp = (float)eval_operand32(1, &breakpoint) / (float)eval_operand32(2, &breakpoint); IFF (config.cpu.dependstats) current->func_unit = it_float; set_operand32(0, temp - (machword)temp, &breakpoint); } INSTRUCTION (lf_sfeq_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; flag = (float)eval_operand32(0, &breakpoint) == (float)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (lf_sfge_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; flag = (float)eval_operand32(0, &breakpoint) >= (float)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (lf_sfgt_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; flag = (float)eval_operand32(0, &breakpoint) > (float)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (lf_sfle_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; flag = (float)eval_operand32(0, &breakpoint) <= (float)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (lf_sflt_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; flag = (float)eval_operand32(0, &breakpoint) < (float)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (lf_sfne_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; flag = (float)eval_operand32(0, &breakpoint) != (float)eval_operand32(1, &breakpoint); setsprbits(SPR_SR, SPR_SR_F, flag); } INSTRUCTION (lf_sub_s) { IFF (config.cpu.dependstats) current->func_unit = it_float; set_operand32(0, (machword)((float)eval_operand32(1, &breakpoint) - (float)eval_operand32(2, &breakpoint)), &breakpoint); } /******* Custom instructions *******/ INSTRUCTION (l_cust1) { /*int destr = current->insn >> 21; int src1r = current->insn >> 15; int src2r = current->insn >> 9;*/ } INSTRUCTION (l_cust2) { } INSTRUCTION (l_cust3) { } INSTRUCTION (l_cust4) { }
Go to most recent revision | Compare with Previous | Blame | View Log