/* execute.c -- DLX dependent simulation
|
/* execute.c -- DLX dependent simulation
|
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
|
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
|
|
|
This file is part of OpenRISC 1000 Architectural Simulator.
|
This file is part of OpenRISC 1000 Architectural Simulator.
|
|
|
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
(at your option) any later version.
|
(at your option) any later version.
|
|
|
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
GNU General Public License for more details.
|
GNU General Public License for more details.
|
|
|
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
|
/* Most of the DLX simulation is done in this file. */
|
/* Most of the DLX simulation is done in this file. */
|
|
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
#include "arch.h"
|
#include "arch.h"
|
|
|
#include "branch_predict.h"
|
#include "branch_predict.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "parse.h"
|
#include "parse.h"
|
#include "trace.h"
|
#include "trace.h"
|
#include "execute.h"
|
#include "execute.h"
|
#include "stats.h"
|
#include "stats.h"
|
|
|
/* General purpose registers. */
|
/* General purpose registers. */
|
machword reg[MAX_GPRS];
|
machword reg[MAX_GPRS];
|
|
|
/* Instruction queue */
|
/* Instruction queue */
|
struct iqueue_entry iqueue[20];
|
struct iqueue_entry iqueue[20];
|
|
|
/* Benchmark multi issue execution */
|
/* Benchmark multi issue execution */
|
int multissue[20];
|
int multissue[20];
|
int supercycles;
|
int supercycles;
|
|
|
/* Load and store stalls */
|
/* Load and store stalls */
|
int loadcycles, storecycles;
|
int loadcycles, storecycles;
|
|
|
/* Result forwarding stall cycles */
|
/* Result forwarding stall cycles */
|
int forwardingcycles;
|
int forwardingcycles;
|
|
|
/* Completition queue */
|
/* Completition queue */
|
struct icomplet_entry icomplet[20];
|
struct icomplet_entry icomplet[20];
|
|
|
/* Program counter */
|
/* Program counter */
|
unsigned long pc;
|
unsigned long pc;
|
|
|
/* Temporary program counter */
|
/* Temporary program counter */
|
unsigned long pctemp;
|
unsigned long pctemp;
|
|
|
/* Cycles counts fetch stages */
|
/* Cycles counts fetch stages */
|
int cycles;
|
int cycles;
|
|
|
/* Implementation specific.
|
/* Implementation specific.
|
Get an actual value of a specific register. */
|
Get an actual value of a specific register. */
|
|
|
machword eval_reg(char *regstr)
|
machword eval_reg(char *regstr)
|
{
|
{
|
int regno;
|
int regno;
|
|
|
regno = atoi(regstr + 1);
|
regno = atoi(regstr + 1);
|
|
|
if (regno < MAX_GPRS)
|
if (regno < MAX_GPRS)
|
return reg[regno];
|
return reg[regno];
|
else {
|
else {
|
printf("\nEXCEPTION: read out of registers\n");
|
printf("\nEXCEPTION: read out of registers\n");
|
cont_run = 0;
|
cont_run = 0;
|
return 0;
|
return 0;
|
}
|
}
|
}
|
}
|
|
|
/* Implementation specific.
|
/* Implementation specific.
|
Set a specific register with value. */
|
Set a specific register with value. */
|
|
|
void set_reg32(char *regstr, unsigned long value)
|
void set_reg32(char *regstr, unsigned long value)
|
{
|
{
|
int regno;
|
int regno;
|
|
|
regno = atoi(regstr + 1);
|
regno = atoi(regstr + 1);
|
|
|
if (regno == 0) /* gpr0 is always zero */
|
if (regno == 0) /* gpr0 is always zero */
|
value = 0;
|
value = 0;
|
|
|
if (regno < MAX_GPRS)
|
if (regno < MAX_GPRS)
|
reg[regno] = value;
|
reg[regno] = value;
|
else {
|
else {
|
printf("\nEXCEPTION: write out of registers\n");
|
printf("\nEXCEPTION: write out of registers\n");
|
cont_run = 0;
|
cont_run = 0;
|
}
|
}
|
|
|
return;
|
return;
|
}
|
}
|
|
|
/* Does srcoperand depend on computation of dstoperand? Return
|
/* Does srcoperand depend on computation of dstoperand? Return
|
non-zero if yes.
|
non-zero if yes.
|
|
|
Cycle t Cycle t+1
|
Cycle t Cycle t+1
|
dst: irrelevant src: immediate always 0
|
dst: irrelevant src: immediate always 0
|
dst: reg1 direct src: reg2 direct 0 if reg1 != reg2
|
dst: reg1 direct src: reg2 direct 0 if reg1 != reg2
|
dst: reg1 disp src: reg2 direct always 0
|
dst: reg1 disp src: reg2 direct always 0
|
dst: reg1 direct src: reg2 disp 0 if reg1 != reg2
|
dst: reg1 direct src: reg2 disp 0 if reg1 != reg2
|
dst: reg1 disp src: reg2 disp always 1 (store must
|
dst: reg1 disp src: reg2 disp always 1 (store must
|
finish before load)
|
finish before load)
|
*/
|
*/
|
|
|
int depend_operands(char *dstoperand, char *srcoperand)
|
int depend_operands(char *dstoperand, char *srcoperand)
|
{
|
{
|
char dst[OPERANDNAME_LEN];
|
char dst[OPERANDNAME_LEN];
|
char src[OPERANDNAME_LEN];
|
char src[OPERANDNAME_LEN];
|
|
|
if (!srcoperand)
|
if (!srcoperand)
|
return 0;
|
return 0;
|
|
|
if (!dstoperand)
|
if (!dstoperand)
|
return 0;
|
return 0;
|
|
|
strcpy(dst, dstoperand);
|
strcpy(dst, dstoperand);
|
strcpy(src, srcoperand);
|
strcpy(src, srcoperand);
|
|
|
if (*src == '#') /* immediate */
|
if (*src == '#') /* immediate */
|
return 0;
|
return 0;
|
else
|
else
|
if (!strstr(src, "("))
|
if (!strstr(src, "("))
|
if (*src == 'r') { /* src: reg direct */
|
if (*src == 'r') { /* src: reg direct */
|
if (!strstr(dst, "("))
|
if (!strstr(dst, "("))
|
if (*dst == 'r')
|
if (*dst == 'r')
|
if (strcmp(dst, src) == 0)
|
if (strcmp(dst, src) == 0)
|
return 1; /* dst: reg direct */
|
return 1; /* dst: reg direct */
|
else
|
else
|
return 0; /* dst: reg direct */
|
return 0; /* dst: reg direct */
|
else
|
else
|
return 0; /* dst: addr */
|
return 0; /* dst: addr */
|
else
|
else
|
return 0; /* dst: reg disp */
|
return 0; /* dst: reg disp */
|
} else
|
} else
|
return 0; /* src: addr */
|
return 0; /* src: addr */
|
else { /* src: register disp */
|
else { /* src: register disp */
|
char *regstr;
|
char *regstr;
|
|
|
regstr = strstr(src, "(r") + 1; /* regstr == "rXX)" */
|
regstr = strstr(src, "(r") + 1; /* regstr == "rXX)" */
|
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */
|
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */
|
|
|
if (!strstr(dst, "("))
|
if (!strstr(dst, "("))
|
if (*dst == 'r')
|
if (*dst == 'r')
|
if (strcmp(dst, regstr) == 0)
|
if (strcmp(dst, regstr) == 0)
|
return 1; /* dst: reg direct */
|
return 1; /* dst: reg direct */
|
else
|
else
|
return 0; /* dst: reg direct */
|
return 0; /* dst: reg direct */
|
else
|
else
|
return 0; /* dst: addr */
|
return 0; /* dst: addr */
|
else
|
else
|
return 1; /* dst: reg disp */
|
return 1; /* dst: reg disp */
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Implementation specific.
|
/* Implementation specific.
|
Get an actual value represented by operand (register direct, register
|
Get an actual value represented by operand (register direct, register
|
indirect (with displacement), immediate etc.).
|
indirect (with displacement), immediate etc.).
|
|
|
#n - immediate n
|
#n - immediate n
|
rXX - register direct
|
rXX - register direct
|
XX - relative or absolute address (labels)
|
XX - relative or absolute address (labels)
|
n(XX) - register indirect (with displacement) */
|
n(XX) - register indirect (with displacement) */
|
|
|
machword eval_operand(char *srcoperand)
|
machword eval_operand(char *srcoperand,int* breakpoint)
|
{
|
{
|
char operand[OPERANDNAME_LEN];
|
char operand[OPERANDNAME_LEN];
|
|
|
strcpy(operand, srcoperand);
|
strcpy(operand, srcoperand);
|
|
|
if (*operand == '#') /* immediate */
|
if (*operand == '#') /* immediate */
|
return strtoul(&operand[1], NULL, 0);
|
return strtoul(&operand[1], NULL, 0);
|
else
|
else
|
if (!strstr(operand, "(")) /* not indirect but ...*/
|
if (!strstr(operand, "(")) /* not indirect but ...*/
|
if (*operand == 'r') /* ... register direct */
|
if (*operand == 'r') /* ... register direct */
|
return eval_reg(operand);
|
return eval_reg(operand);
|
|
|
else /* ... rel. or abs. address */
|
else /* ... rel. or abs. address */
|
return eval_label(operand);
|
return eval_label(operand);
|
else { /* register indirect */
|
else { /* register indirect */
|
int disp; /* with possible displacement */
|
int disp; /* with possible displacement */
|
char *regstr;
|
char *regstr;
|
unsigned int memaddr;
|
unsigned int memaddr;
|
|
|
disp = atoi(operand); /* operand == "nn(rXX)" */
|
disp = atoi(operand); /* operand == "nn(rXX)" */
|
regstr = strstr(operand, "(r") + 1; /* regstr == "rXX)" */
|
regstr = strstr(operand, "(r") + 1; /* regstr == "rXX)" */
|
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */
|
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */
|
memaddr = eval_reg(regstr) + disp;
|
memaddr = eval_reg(regstr) + disp;
|
|
|
return eval_mem32(memaddr);
|
return eval_mem32(memaddr,breakpoint);
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Implementation specific.
|
/* Implementation specific.
|
Set destination operand (register direct, register indirect
|
Set destination operand (register direct, register indirect
|
(with displacement) with value. */
|
(with displacement) with value. */
|
|
|
void set_operand(char *dstoperand, unsigned long value)
|
void set_operand(char *dstoperand, unsigned long value,int* breakpoint)
|
{
|
{
|
char operand[OPERANDNAME_LEN];
|
char operand[OPERANDNAME_LEN];
|
|
|
strcpy(operand, dstoperand);
|
strcpy(operand, dstoperand);
|
|
|
if (*operand == '#') /* immediate */
|
if (*operand == '#') /* immediate */
|
printf("INTERNAL ERROR: Can't set immediate operand.\n");
|
printf("INTERNAL ERROR: Can't set immediate operand.\n");
|
else
|
else
|
if (!strstr(operand, "(")) /* not indirect but ...*/
|
if (!strstr(operand, "(")) /* not indirect but ...*/
|
if (*operand == 'r') /* ... register direct */
|
if (*operand == 'r') /* ... register direct */
|
set_reg32(operand, value);
|
set_reg32(operand, value);
|
else /* ... rel. or abs. address */
|
else /* ... rel. or abs. address */
|
printf("INTERNAL ERROR: Can't set addr operand.\n");
|
printf("INTERNAL ERROR: Can't set addr operand.\n");
|
else { /* register indirect */
|
else { /* register indirect */
|
int disp; /* with possible displacement */
|
int disp; /* with possible displacement */
|
char *regstr;
|
char *regstr;
|
unsigned int memaddr;
|
unsigned int memaddr;
|
|
|
disp = atoi(operand); /* operand == "nn(rXX)" */
|
disp = atoi(operand); /* operand == "nn(rXX)" */
|
regstr = strstr(operand, "(r") + 1; /* regstr == "rXX)" */
|
regstr = strstr(operand, "(r") + 1; /* regstr == "rXX)" */
|
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */
|
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */
|
memaddr = eval_reg(regstr) + disp;
|
memaddr = eval_reg(regstr) + disp;
|
|
|
set_mem32(memaddr, value);
|
set_mem32(memaddr, value, breakpoint);
|
}
|
}
|
|
|
return;
|
return;
|
}
|
}
|
|
|
void reset()
|
void reset()
|
{
|
{
|
cycles = 0;
|
cycles = 0;
|
supercycles = 0;
|
supercycles = 0;
|
loadcycles = 0;
|
loadcycles = 0;
|
storecycles = 0;
|
storecycles = 0;
|
forwardingcycles = 0;
|
forwardingcycles = 0;
|
memset(reg, 0, sizeof(reg));
|
memset(reg, 0, sizeof(reg));
|
memset(iqueue, 0, sizeof(iqueue));
|
memset(iqueue, 0, sizeof(iqueue));
|
memset(icomplet, 0, sizeof(icomplet));
|
memset(icomplet, 0, sizeof(icomplet));
|
pctemp = eval_label("_main");
|
pctemp = eval_label("_main");
|
pc = pctemp;
|
pc = pctemp;
|
set_reg32(STACK_REG , MEMORY_LEN - STACK_SIZE);
|
set_reg32(STACK_REG , MEMORY_LEN - STACK_SIZE);
|
}
|
}
|
|
|
void fetch()
|
void fetch()
|
{
|
{
|
/* Cycles after reset. */
|
/* Cycles after reset. */
|
cycles++;
|
cycles++;
|
|
|
/* Simulate instruction cache */
|
/* Simulate instruction cache */
|
ic_simulate(pc);
|
ic_simulate(pc);
|
|
|
/* Fetch instruction. */
|
/* Fetch instruction. */
|
strcpy(iqueue[0].insn, mem[pc].insn->insn);
|
strcpy(iqueue[0].insn, mem[pc].insn->insn);
|
strcpy(iqueue[0].op1, mem[pc].insn->op1);
|
strcpy(iqueue[0].op1, mem[pc].insn->op1);
|
strcpy(iqueue[0].op2, mem[pc].insn->op2);
|
strcpy(iqueue[0].op2, mem[pc].insn->op2);
|
strcpy(iqueue[0].op3, mem[pc].insn->op3);
|
strcpy(iqueue[0].op3, mem[pc].insn->op3);
|
iqueue[0].insn_addr = pc;
|
iqueue[0].insn_addr = pc;
|
iqueue[0].dependdst = NULL;
|
iqueue[0].dependdst = NULL;
|
iqueue[0].dependsrc1 = NULL;
|
iqueue[0].dependsrc1 = NULL;
|
iqueue[0].dependsrc2 = NULL;
|
iqueue[0].dependsrc2 = NULL;
|
|
|
/* Increment program counter. */
|
/* Increment program counter. */
|
pc = pctemp;
|
pc = pctemp;
|
pctemp += 4;
|
pctemp += 4;
|
|
|
/* Check for breakpoint. */
|
/* Check for breakpoint. */
|
if (mem[pc].brk)
|
if (mem[pc].brk)
|
cont_run = 0; /* Breakpoint set. */
|
cont_run = 0; /* Breakpoint set. */
|
|
|
return;
|
return;
|
}
|
}
|
|
|
void decode(struct iqueue_entry *cur)
|
void decode(struct iqueue_entry *cur)
|
{
|
{
|
|
int breakpoint = 0;
|
|
|
cur->dependdst = cur->op1;
|
cur->dependdst = cur->op1;
|
cur->dependsrc1 = cur->op2; /* for calculating register */
|
cur->dependsrc1 = cur->op2; /* for calculating register */
|
cur->dependsrc2 = cur->op3; /* dependency */
|
cur->dependsrc2 = cur->op3; /* dependency */
|
|
|
cur->func_unit = unknown;
|
cur->func_unit = unknown;
|
|
|
if (strcmp(cur->insn, "sw") == 0) {
|
if (strcmp(cur->insn, "sw") == 0) {
|
cur->func_unit = store;
|
cur->func_unit = store;
|
set_operand(cur->op1, eval_operand(cur->op2));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sb") == 0) {
|
if (strcmp(cur->insn, "sb") == 0) {
|
cur->func_unit = store;
|
cur->func_unit = store;
|
set_operand(cur->op1, (eval_operand(cur->op2) << 24) + (eval_operand(cur->op1) & 0xffffff));
|
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 24) + (eval_operand(cur->op1,&breakpoint) & 0xffffff),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sh") == 0) {
|
if (strcmp(cur->insn, "sh") == 0) {
|
cur->func_unit = store;
|
cur->func_unit = store;
|
set_operand(cur->op1, (eval_operand(cur->op2) << 16) + (eval_operand(cur->op1) & 0xffff));
|
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 16) + (eval_operand(cur->op1,&breakpoint) & 0xffff),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "lw") == 0) {
|
if (strcmp(cur->insn, "lw") == 0) {
|
cur->func_unit = load;
|
cur->func_unit = load;
|
set_operand(cur->op1, eval_operand(cur->op2));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "lb") == 0) {
|
if (strcmp(cur->insn, "lb") == 0) {
|
signed char temp = (eval_operand(cur->op2) >> 24);
|
signed char temp = (eval_operand(cur->op2,&breakpoint) >> 24);
|
cur->func_unit = load;
|
cur->func_unit = load;
|
set_operand(cur->op1, temp);
|
set_operand(cur->op1, temp,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "lbu") == 0) {
|
if (strcmp(cur->insn, "lbu") == 0) {
|
unsigned char temp = (eval_operand(cur->op2) >> 24);
|
unsigned char temp = (eval_operand(cur->op2,&breakpoint) >> 24);
|
cur->func_unit = load;
|
cur->func_unit = load;
|
set_operand(cur->op1, temp);
|
set_operand(cur->op1, temp,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "lh") == 0) {
|
if (strcmp(cur->insn, "lh") == 0) {
|
signed short temp = (eval_operand(cur->op2) >> 16);
|
signed short temp = (eval_operand(cur->op2,&breakpoint) >> 16);
|
cur->func_unit = load;
|
cur->func_unit = load;
|
set_operand(cur->op1, temp);
|
set_operand(cur->op1, temp,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "lhu") == 0) {
|
if (strcmp(cur->insn, "lhu") == 0) {
|
unsigned short temp = (eval_operand(cur->op2) >> 16);
|
unsigned short temp = (eval_operand(cur->op2,&breakpoint) >> 16);
|
cur->func_unit = load;
|
cur->func_unit = load;
|
set_operand(cur->op1, temp);
|
set_operand(cur->op1, temp,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "lwi") == 0) {
|
if (strcmp(cur->insn, "lwi") == 0) {
|
cur->func_unit = movimm;
|
cur->func_unit = movimm;
|
set_operand(cur->op1, eval_operand(cur->op2));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "lhi") == 0) {
|
if (strcmp(cur->insn, "lhi") == 0) {
|
cur->func_unit = movimm;
|
cur->func_unit = movimm;
|
set_operand(cur->op1, eval_operand(cur->op2) << 16);
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << 16,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "and") == 0) {
|
if (strcmp(cur->insn, "and") == 0) {
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
set_operand(cur->op1, eval_operand(cur->op2) & eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "andi") == 0) {
|
if (strcmp(cur->insn, "andi") == 0) {
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
set_operand(cur->op1, eval_operand(cur->op2) & eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "or") == 0) {
|
if (strcmp(cur->insn, "or") == 0) {
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
set_operand(cur->op1, eval_operand(cur->op2) | eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "ori") == 0) {
|
if (strcmp(cur->insn, "ori") == 0) {
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
set_operand(cur->op1, eval_operand(cur->op2) | eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "xor") == 0) {
|
if (strcmp(cur->insn, "xor") == 0) {
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
set_operand(cur->op1, eval_operand(cur->op2) ^ eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) ^ eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "add") == 0) {
|
if (strcmp(cur->insn, "add") == 0) {
|
signed long temp3, temp2, temp1;
|
signed long temp3, temp2, temp1;
|
signed char temp4;
|
signed char temp4;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 + temp3;
|
temp1 = temp2 + temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
|
|
temp4 = temp1;
|
temp4 = temp1;
|
if (temp4 == temp1)
|
if (temp4 == temp1)
|
mstats.byteadd++;
|
mstats.byteadd++;
|
} else
|
} else
|
if (strcmp(cur->insn, "addi") == 0) {
|
if (strcmp(cur->insn, "addi") == 0) {
|
signed long temp3, temp2, temp1;
|
signed long temp3, temp2, temp1;
|
signed char temp4;
|
signed char temp4;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 + temp3;
|
temp1 = temp2 + temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
|
|
temp4 = temp1;
|
temp4 = temp1;
|
if (temp4 == temp1)
|
if (temp4 == temp1)
|
mstats.byteadd++;
|
mstats.byteadd++;
|
} else
|
} else
|
if (strcmp(cur->insn, "addui") == 0) {
|
if (strcmp(cur->insn, "addui") == 0) {
|
unsigned long temp3, temp2, temp1;
|
unsigned long temp3, temp2, temp1;
|
unsigned char temp4;
|
unsigned char temp4;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 + temp3;
|
temp1 = temp2 + temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
|
|
temp4 = temp1;
|
temp4 = temp1;
|
if (temp4 == temp1)
|
if (temp4 == temp1)
|
mstats.byteadd++;
|
mstats.byteadd++;
|
} else
|
} else
|
if (strcmp(cur->insn, "sub") == 0) {
|
if (strcmp(cur->insn, "sub") == 0) {
|
signed long temp3, temp2, temp1;
|
signed long temp3, temp2, temp1;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 - temp3;
|
temp1 = temp2 - temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "subui") == 0) {
|
if (strcmp(cur->insn, "subui") == 0) {
|
unsigned long temp3, temp2, temp1;
|
unsigned long temp3, temp2, temp1;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 - temp3;
|
temp1 = temp2 - temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "subi") == 0) {
|
if (strcmp(cur->insn, "subi") == 0) {
|
signed long temp3, temp2, temp1;
|
signed long temp3, temp2, temp1;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 - temp3;
|
temp1 = temp2 - temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "mul") == 0) {
|
if (strcmp(cur->insn, "mul") == 0) {
|
signed long temp3, temp2, temp1;
|
signed long temp3, temp2, temp1;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 * temp3;
|
temp1 = temp2 * temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "div") == 0) {
|
if (strcmp(cur->insn, "div") == 0) {
|
signed long temp3, temp2, temp1;
|
signed long temp3, temp2, temp1;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 / temp3;
|
temp1 = temp2 / temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "divu") == 0) {
|
if (strcmp(cur->insn, "divu") == 0) {
|
unsigned long temp3, temp2, temp1;
|
unsigned long temp3, temp2, temp1;
|
|
|
cur->func_unit = arith;
|
cur->func_unit = arith;
|
temp3 = eval_operand(cur->op3);
|
temp3 = eval_operand(cur->op3,&breakpoint);
|
temp2 = eval_operand(cur->op2);
|
temp2 = eval_operand(cur->op2,&breakpoint);
|
temp1 = temp2 / temp3;
|
temp1 = temp2 / temp3;
|
set_operand(cur->op1, temp1);
|
set_operand(cur->op1, temp1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "slli") == 0) {
|
if (strcmp(cur->insn, "slli") == 0) {
|
cur->func_unit = shift;
|
cur->func_unit = shift;
|
set_operand(cur->op1, eval_operand(cur->op2) << eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sll") == 0) {
|
if (strcmp(cur->insn, "sll") == 0) {
|
cur->func_unit = shift;
|
cur->func_unit = shift;
|
set_operand(cur->op1, eval_operand(cur->op2) << eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "srl") == 0) {
|
if (strcmp(cur->insn, "srl") == 0) {
|
cur->func_unit = shift;
|
cur->func_unit = shift;
|
set_operand(cur->op1, eval_operand(cur->op2) >> eval_operand(cur->op3));
|
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) >> eval_operand(cur->op3,&breakpoint),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "srai") == 0) {
|
if (strcmp(cur->insn, "srai") == 0) {
|
cur->func_unit = shift;
|
cur->func_unit = shift;
|
set_operand(cur->op1, (signed)eval_operand(cur->op2) / (1 << eval_operand(cur->op3)));
|
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sra") == 0) {
|
if (strcmp(cur->insn, "sra") == 0) {
|
cur->func_unit = shift;
|
cur->func_unit = shift;
|
set_operand(cur->op1, (signed)eval_operand(cur->op2) / (1 << eval_operand(cur->op3)));
|
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "jal") == 0) {
|
if (strcmp(cur->insn, "jal") == 0) {
|
cur->func_unit = jump;
|
cur->func_unit = jump;
|
pctemp = eval_operand(cur->op1);
|
pctemp = eval_operand(cur->op1,&breakpoint);
|
set_reg32(LINK_REG, pc + 4);
|
set_reg32(LINK_REG, pc + 4);
|
} else
|
} else
|
if (strcmp(cur->insn, "jr") == 0) {
|
if (strcmp(cur->insn, "jr") == 0) {
|
cur->func_unit = jump;
|
cur->func_unit = jump;
|
cur->dependsrc1 = cur->op1;
|
cur->dependsrc1 = cur->op1;
|
pctemp = eval_operand(cur->op1);
|
pctemp = eval_operand(cur->op1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "j") == 0) {
|
if (strcmp(cur->insn, "j") == 0) {
|
cur->func_unit = jump;
|
cur->func_unit = jump;
|
pctemp = eval_operand(cur->op1);
|
pctemp = eval_operand(cur->op1,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "nop") == 0) {
|
if (strcmp(cur->insn, "nop") == 0) {
|
cur->func_unit = nop;
|
cur->func_unit = nop;
|
} else
|
} else
|
if (strcmp(cur->insn, "beqz") == 0) {
|
if (strcmp(cur->insn, "beqz") == 0) {
|
cur->func_unit = branch;
|
cur->func_unit = branch;
|
cur->dependsrc1 = cur->op1;
|
cur->dependsrc1 = cur->op1;
|
if (eval_operand(cur->op1) == 0) {
|
if (eval_operand(cur->op1,&breakpoint) == 0) {
|
pctemp = eval_operand(cur->op2);
|
pctemp = eval_operand(cur->op2,&breakpoint);
|
mstats.beqz.taken++;
|
mstats.beqz.taken++;
|
bpb_update(cur->insn_addr, 1);
|
bpb_update(cur->insn_addr, 1);
|
btic_update(pctemp);
|
btic_update(pctemp);
|
} else {
|
} else {
|
mstats.beqz.nottaken++;
|
mstats.beqz.nottaken++;
|
bpb_update(cur->insn_addr, 0);
|
bpb_update(cur->insn_addr, 0);
|
btic_update(pc);
|
btic_update(pc);
|
}
|
}
|
} else
|
} else
|
if (strcmp(cur->insn, "bnez") == 0) {
|
if (strcmp(cur->insn, "bnez") == 0) {
|
cur->func_unit = branch;
|
cur->func_unit = branch;
|
cur->dependsrc1 = cur->op1;
|
cur->dependsrc1 = cur->op1;
|
if (eval_operand(cur->op1) != 0) {
|
if (eval_operand(cur->op1,&breakpoint) != 0) {
|
pctemp = eval_operand(cur->op2);
|
pctemp = eval_operand(cur->op2,&breakpoint);
|
mstats.bnez.taken++;
|
mstats.bnez.taken++;
|
bpb_update(cur->insn_addr, 1);
|
bpb_update(cur->insn_addr, 1);
|
btic_update(pctemp);
|
btic_update(pctemp);
|
} else {
|
} else {
|
mstats.bnez.nottaken++;
|
mstats.bnez.nottaken++;
|
bpb_update(cur->insn_addr, 0);
|
bpb_update(cur->insn_addr, 0);
|
btic_update(pc);
|
btic_update(pc);
|
}
|
}
|
} else
|
} else
|
if (strcmp(cur->insn, "seq") == 0) {
|
if (strcmp(cur->insn, "seq") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if (eval_operand(cur->op2) == eval_operand(cur->op3))
|
if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "snei") == 0) {
|
if (strcmp(cur->insn, "snei") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if (eval_operand(cur->op2) != eval_operand(cur->op3))
|
if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sne") == 0) {
|
if (strcmp(cur->insn, "sne") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if (eval_operand(cur->op2) != eval_operand(cur->op3))
|
if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "seqi") == 0) {
|
if (strcmp(cur->insn, "seqi") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if (eval_operand(cur->op2) == eval_operand(cur->op3))
|
if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sgt") == 0) {
|
if (strcmp(cur->insn, "sgt") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((signed)eval_operand(cur->op2) >
|
if ((signed)eval_operand(cur->op2,&breakpoint) >
|
(signed)eval_operand(cur->op3))
|
(signed)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sgtui") == 0) {
|
if (strcmp(cur->insn, "sgtui") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((unsigned)eval_operand(cur->op2) >
|
if ((unsigned)eval_operand(cur->op2,&breakpoint) >
|
(unsigned)eval_operand(cur->op3))
|
(unsigned)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sgeui") == 0) {
|
if (strcmp(cur->insn, "sgeui") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((unsigned)eval_operand(cur->op2) >=
|
if ((unsigned)eval_operand(cur->op2,&breakpoint) >=
|
(unsigned)eval_operand(cur->op3))
|
(unsigned)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sgei") == 0) {
|
if (strcmp(cur->insn, "sgei") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((signed)eval_operand(cur->op2) >= (signed)eval_operand(cur->op3))
|
if ((signed)eval_operand(cur->op2,&breakpoint) >= (signed)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sgti") == 0) {
|
if (strcmp(cur->insn, "sgti") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((signed)eval_operand(cur->op2) >
|
if ((signed)eval_operand(cur->op2,&breakpoint) >
|
(signed)eval_operand(cur->op3))
|
(signed)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "slt") == 0) {
|
if (strcmp(cur->insn, "slt") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((signed)eval_operand(cur->op2) <
|
if ((signed)eval_operand(cur->op2,&breakpoint) <
|
(signed)eval_operand(cur->op3))
|
(signed)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "slti") == 0) {
|
if (strcmp(cur->insn, "slti") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((signed)eval_operand(cur->op2) <
|
if ((signed)eval_operand(cur->op2,&breakpoint) <
|
(signed)eval_operand(cur->op3))
|
(signed)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sle") == 0) {
|
if (strcmp(cur->insn, "sle") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((signed)eval_operand(cur->op2) <=
|
if ((signed)eval_operand(cur->op2,&breakpoint) <=
|
(signed)eval_operand(cur->op3))
|
(signed)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "slei") == 0) {
|
if (strcmp(cur->insn, "slei") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((signed)eval_operand(cur->op2) <=
|
if ((signed)eval_operand(cur->op2,&breakpoint) <=
|
(signed)eval_operand(cur->op3))
|
(signed)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sleui") == 0) {
|
if (strcmp(cur->insn, "sleui") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((unsigned)eval_operand(cur->op2) <=
|
if ((unsigned)eval_operand(cur->op2,&breakpoint) <=
|
(unsigned)eval_operand(cur->op3))
|
(unsigned)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "sleu") == 0) {
|
if (strcmp(cur->insn, "sleu") == 0) {
|
cur->func_unit = compare;
|
cur->func_unit = compare;
|
if ((unsigned)eval_operand(cur->op2) <=
|
if ((unsigned)eval_operand(cur->op2,&breakpoint) <=
|
(unsigned)eval_operand(cur->op3))
|
(unsigned)eval_operand(cur->op3,&breakpoint))
|
set_operand(cur->op1, 1);
|
set_operand(cur->op1, 1,&breakpoint);
|
else
|
else
|
set_operand(cur->op1, 0);
|
set_operand(cur->op1, 0,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "simrdtsc") == 0) {
|
if (strcmp(cur->insn, "simrdtsc") == 0) {
|
set_operand(cur->op1, cycles+loadcycles+storecycles+forwardingcycles);
|
set_operand(cur->op1, cycles+loadcycles+storecycles+forwardingcycles,&breakpoint);
|
} else
|
} else
|
if (strcmp(cur->insn, "simprintf") == 0) {
|
if (strcmp(cur->insn, "simprintf") == 0) {
|
unsigned long stackaddr;
|
unsigned long stackaddr;
|
|
|
stackaddr = eval_reg(FRAME_REG);
|
stackaddr = eval_reg(FRAME_REG);
|
simprintf(stackaddr, 0);
|
simprintf(stackaddr, 0);
|
/* printf("simprintf %x %x %x\n", stackaddr, fmtaddr, args); */
|
/* printf("simprintf %x %x %x\n", stackaddr, fmtaddr, args); */
|
} else {
|
} else {
|
printf("\nEXCEPTION: illegal opcode %s ", cur->insn);
|
printf("\nEXCEPTION: illegal opcode %s ", cur->insn);
|
printf("at %.8lx\n", cur->insn_addr);
|
printf("at %.8lx\n", cur->insn_addr);
|
cont_run = 0;
|
cont_run = 0;
|
}
|
}
|
|
|
/* Dynamic, dependency stats. */
|
/* Dynamic, dependency stats. */
|
adddstats(icomplet[0].insn, iqueue[0].insn, 1, check_depend());
|
adddstats(icomplet[0].insn, iqueue[0].insn, 1, check_depend());
|
|
|
/* Dynamic, functional units stats. */
|
/* Dynamic, functional units stats. */
|
addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend());
|
addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend());
|
|
|
/* Dynamic, single stats. */
|
/* Dynamic, single stats. */
|
addsstats(iqueue[0].insn, 1, 0);
|
addsstats(iqueue[0].insn, 1, 0);
|
|
|
if (cur->func_unit == store)
|
if (cur->func_unit == store)
|
storecycles += 0;
|
storecycles += 0;
|
|
|
if (cur->func_unit == load)
|
if (cur->func_unit == load)
|
loadcycles += 0;
|
loadcycles += 0;
|
|
|
if (check_depend())
|
if (check_depend())
|
forwardingcycles += 0;
|
forwardingcycles += 0;
|
|
|
/* Pseudo multiple issue benchmark */
|
/* Pseudo multiple issue benchmark */
|
if ((multissue[cur->func_unit] == 0) || (check_depend())) {
|
if ((multissue[cur->func_unit] == 0) || (check_depend())) {
|
int i;
|
int i;
|
for (i = 0; i < 20; i++)
|
for (i = 0; i < 20; i++)
|
multissue[i] = 9;
|
multissue[i] = 9;
|
supercycles++;
|
supercycles++;
|
multissue[arith] = 9;
|
multissue[arith] = 9;
|
multissue[store] = 9;
|
multissue[store] = 9;
|
multissue[load] = 9;
|
multissue[load] = 9;
|
}
|
}
|
multissue[cur->func_unit]--;
|
multissue[cur->func_unit]--;
|
|
|
return;
|
return;
|
}
|
}
|
|
|
void execute()
|
void execute()
|
{
|
{
|
int i;
|
int i;
|
|
|
/* Here comes real execution someday... */
|
/* Here comes real execution someday... */
|
|
|
/* Instruction waits in completition buffer until retired. */
|
/* Instruction waits in completition buffer until retired. */
|
strcpy(icomplet[0].insn, iqueue[0].insn);
|
strcpy(icomplet[0].insn, iqueue[0].insn);
|
strcpy(icomplet[0].op1, iqueue[0].op1);
|
strcpy(icomplet[0].op1, iqueue[0].op1);
|
strcpy(icomplet[0].op2, iqueue[0].op2);
|
strcpy(icomplet[0].op2, iqueue[0].op2);
|
strcpy(icomplet[0].op3, iqueue[0].op3);
|
strcpy(icomplet[0].op3, iqueue[0].op3);
|
icomplet[0].func_unit = iqueue[0].func_unit;
|
icomplet[0].func_unit = iqueue[0].func_unit;
|
icomplet[0].insn_addr = iqueue[0].insn_addr;
|
icomplet[0].insn_addr = iqueue[0].insn_addr;
|
|
|
if (iqueue[0].dependdst == iqueue[0].op1)
|
if (iqueue[0].dependdst == iqueue[0].op1)
|
icomplet[0].dependdst = icomplet[0].op1;
|
icomplet[0].dependdst = icomplet[0].op1;
|
else
|
else
|
if (iqueue[0].dependdst == iqueue[0].op2)
|
if (iqueue[0].dependdst == iqueue[0].op2)
|
icomplet[0].dependdst = icomplet[0].op2;
|
icomplet[0].dependdst = icomplet[0].op2;
|
else
|
else
|
if (iqueue[0].dependdst == iqueue[0].op3)
|
if (iqueue[0].dependdst == iqueue[0].op3)
|
icomplet[0].dependdst = icomplet[0].op3;
|
icomplet[0].dependdst = icomplet[0].op3;
|
else
|
else
|
icomplet[0].dependdst = NULL;
|
icomplet[0].dependdst = NULL;
|
|
|
if (iqueue[0].dependsrc1 == iqueue[0].op1)
|
if (iqueue[0].dependsrc1 == iqueue[0].op1)
|
icomplet[0].dependsrc1 = icomplet[0].op1;
|
icomplet[0].dependsrc1 = icomplet[0].op1;
|
else
|
else
|
if (iqueue[0].dependsrc1 == iqueue[0].op2)
|
if (iqueue[0].dependsrc1 == iqueue[0].op2)
|
icomplet[0].dependsrc1 = icomplet[0].op2;
|
icomplet[0].dependsrc1 = icomplet[0].op2;
|
else
|
else
|
if (iqueue[0].dependsrc1 == iqueue[0].op3)
|
if (iqueue[0].dependsrc1 == iqueue[0].op3)
|
icomplet[0].dependsrc1 = icomplet[0].op3;
|
icomplet[0].dependsrc1 = icomplet[0].op3;
|
else
|
else
|
icomplet[0].dependsrc1 = NULL;
|
icomplet[0].dependsrc1 = NULL;
|
|
|
if (iqueue[0].dependsrc2 == iqueue[0].op1)
|
if (iqueue[0].dependsrc2 == iqueue[0].op1)
|
icomplet[0].dependsrc2 = icomplet[0].op1;
|
icomplet[0].dependsrc2 = icomplet[0].op1;
|
else
|
else
|
if (iqueue[0].dependsrc2 == iqueue[0].op2)
|
if (iqueue[0].dependsrc2 == iqueue[0].op2)
|
icomplet[0].dependsrc2 = icomplet[0].op2;
|
icomplet[0].dependsrc2 = icomplet[0].op2;
|
else
|
else
|
if (iqueue[0].dependsrc2 == iqueue[0].op3)
|
if (iqueue[0].dependsrc2 == iqueue[0].op3)
|
icomplet[0].dependsrc2 = icomplet[0].op3;
|
icomplet[0].dependsrc2 = icomplet[0].op3;
|
else
|
else
|
icomplet[0].dependsrc2 = NULL;
|
icomplet[0].dependsrc2 = NULL;
|
|
|
/* History of execution */
|
/* History of execution */
|
for (i = HISTEXEC_LEN - 1; i; i--)
|
for (i = HISTEXEC_LEN - 1; i; i--)
|
histexec[i] = histexec[i - 1];
|
histexec[i] = histexec[i - 1];
|
histexec[0] = icomplet[0].insn_addr; /* add last insn */
|
histexec[0] = icomplet[0].insn_addr; /* add last insn */
|
|
|
return;
|
return;
|
}
|
}
|
|
|
void dumpreg()
|
void dumpreg()
|
{
|
{
|
int i;
|
int i;
|
|
|
printf("\n\nIQ[0]:");
|
printf("\n\nIQ[0]:");
|
dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4);
|
dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4);
|
printf(" (just executed)\tCYCLES: %u \nSuperscalar CYCLES: %u\n", cycles, supercycles);
|
printf(" (just executed)\tCYCLES: %u \nSuperscalar CYCLES: %u\n", cycles, supercycles);
|
printf("Additional LOAD CYCLES: %u STORE CYCLES: %u\n", loadcycles, storecycles);
|
printf("Additional LOAD CYCLES: %u STORE CYCLES: %u\n", loadcycles, storecycles);
|
printf("Additional RESULT FORWARDING CYCLES: %u\nPC:", forwardingcycles);
|
printf("Additional RESULT FORWARDING CYCLES: %u\nPC:", forwardingcycles);
|
dumpmemory(pc, pc + 4);
|
dumpmemory(pc, pc + 4);
|
printf(" (next insn)");
|
printf(" (next insn)");
|
for(i = 0; i < MAX_GPRS; i++) {
|
for(i = 0; i < MAX_GPRS; i++) {
|
if (i % 4 == 0)
|
if (i % 4 == 0)
|
printf("\n");
|
printf("\n");
|
printf("GPR%.2u: %.8lx ", i, reg[i]);
|
printf("GPR%.2u: %.8lx ", i, reg[i]);
|
}
|
}
|
}
|
}
|
|
|