OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [or1k-1_0/] [or1ksim/] [cpu/] [or32/] [execute.c] - Rev 1765

Compare with Previous | Blame | View Log

/* execute.c -- OR1K architecture dependent simulation
   Copyright (C) 1999 Damjan Lampret, lampret@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. */
 
/* Most of the OR1K simulation is done in here. */
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
 
#include "arch.h"
 
#include "branch_predict.h"
#include "abstract.h"
#include "parse.h"
#include "trace.h"
#include "execute.h"
#include "stats.h"
 
/* General purpose registers. */
machword reg[MAX_GPRS];
 
/* Instruction queue */
struct iqueue_entry iqueue[20];
 
/* Benchmark multi issue execution */
int multissue[20];
int supercycles;
 
/* Completition queue */
struct icomplet_entry icomplet[20];
 
/* Program counter */
unsigned long pc;
 
/* Temporary program counter */
unsigned long pctemp;
 
/* CCR */
int flag;
 
/* CCR (for dependency calculation) */
char ccr_flag[10] = "flag";
 
/* Cycles counts fetch stages */
int cycles;
 
/* Implementation specific.
   Get an actual value of a specific register. */
 
machword eval_reg(char *regstr)
{
	int regno;
 
	regno = atoi(regstr + 1);
 
	if (regno < MAX_GPRS)
		return reg[regno];
	else {
		printf("\nEXCEPTION: read out of registers\n");
		cont_run = 0;
		return 0;
	}
}
 
/* Implementation specific.
   Set a specific register with value. */
 
void set_reg32(char *regstr, unsigned long value)
{
	int regno;
 
#if 0	
	if (strcmp(regstr, FRAME_REG) == 0) {
		printf("FP (%s) modified by insn at %x. ", FRAME_REG, pc);
		printf("Old:%.8lx  New:%.8lx\n", eval_reg(regstr), value);
	}
 
	if (strcmp(regstr, STACK_REG) == 0) {
		printf("SP (%s) modified by insn at %x. ", STACK_REG, pc);
		printf("Old:%.8lx  New:%.8lx\n", eval_reg(regstr), value);
	}
#endif
	regno = atoi(regstr + 1);
 
	if (regno == 0)		/* gpr0 is always zero */
		value = 0;
 
	if (regno < MAX_GPRS)
		reg[regno] = value;
	else {
		printf("\nEXCEPTION: write out of registers\n");
		cont_run = 0;
	}
	return;
}
 
/* Does srcoperand depend on computation of dstoperand? Return
   non-zero if yes.
 
 Cycle t		 Cycle t+1
dst: irrelevant		src: immediate			always 0
dst: reg1 direct	src: reg2 direct		0 if reg1 != reg2
dst: reg1 disp		src: reg2 direct		always 0
dst: reg1 direct	src: reg2 disp			0 if reg1 != reg2
dst: reg1 disp		src: reg2 disp 			always 1 (store must
							finish before load)
*/
 
int depend_operands(char *dstoperand, char *srcoperand)
{
	char dst[OPERANDNAME_LEN];
	char src[OPERANDNAME_LEN];
 
	if (!srcoperand)
		return 0;
 
	if (!dstoperand)
		return 0;
 
	strcpy(dst, dstoperand);
	strcpy(src, srcoperand);
 
	if (*src == '#')		/* immediate */
		return 0;
	else
	if (strstr(src, "lo(") || strstr(src, "hi("))
		return 0;
	else
	if (!strstr(src, "(")) 
		if (*src == 'r') {	/* src: reg direct */
			if (!strstr(dst, "("))
				if (*dst == 'r')
					if (strcmp(dst, src) == 0)
						return 1; /* dst: reg direct */
					else
						return 0; /* dst: reg direct */
				else
					return 0; /* dst: addr */
			else
				return 0; /* dst: reg disp */
		} else
			return 0;	/* src: addr */
	else {				/* src: register disp */
		char *regstr;
 
		regstr = strstr(src, "(r") + 1;	/* regstr == "rXX)" */
		*strstr(regstr, ")") = '\0';		/* regstr == "rXX" */
 
		if (!strstr(dst, "("))
			if (*dst == 'r')
				if (strcmp(dst, regstr) == 0)
					return 1; /* dst: reg direct */
				else
					return 0; /* dst: reg direct */
			else
				return 0; /* dst: addr */
		else
			return 1; /* dst: reg disp */
	}	
 
	return 0;
}
 
/* Implementation specific.
   Get an actual value represented by operand (register direct, register
   indirect (with displacement), immediate etc.).
 
   #n		- immediate n
   rXX		- register direct
   XX		- relative or absolute address (labels)
   n(XX) 	- register indirect (with displacement) */
 
machword eval_operand(char *srcoperand)
{
	char operand[OPERANDNAME_LEN];
 
	strcpy(operand, srcoperand);
 
	if (*operand == '#')		/* immediate */
		return strtoul(&operand[1], NULL, 0);
	else
	if (((*operand == '-') || isdigit(*operand)) && !strstr(operand, "(")) {
		/* immediate */
		return strtoul(operand, NULL, 0);
	} else
	if (strncmp(operand, "lo(", 3) == 0) {
		*strchr(operand, ')') = '\0';
		if ((operand[3] == '-') || isdigit(operand[3]))
			return (unsigned long)strtol(&operand[3], NULL, 0) & 0xffff;
		else
			return eval_operand(&operand[3]) & 0xffff;
	} else 
	if (strncmp(operand, "hi(", 3) == 0) {
		*strchr(operand, ')') = '\0';
		if ((operand[3] == '-') || isdigit(operand[3]))
			return (unsigned long)strtol(&operand[3], NULL, 0) >> 16;
		else
			return eval_operand(&operand[3]) >> 16;
	} else 
	if (!strstr(operand, "(")) 	/* not indirect but ...*/
		if (*operand == 'r') 	/* ... register direct */
			return eval_reg(operand);
 
		else 			/* ... rel. or abs. address */
			return eval_label(operand);
	else {				/* register indirect */
		int disp;		/* with possible displacement */
		char *regstr;
		unsigned int memaddr;
 
		disp = atoi(operand);	/* operand == "nn(rXX)" */
		debug("eval_operand: disp=%u");
		regstr = strstr(operand, "(r") + 1;	/* regstr == "rXX)" */
		*strstr(regstr, ")") = '\0';		/* regstr == "rXX" */
		debug("eval_operand: regstr=%s", regstr);
		memaddr = eval_reg(regstr) + disp;
 
		return eval_mem32(memaddr);
	}
 
	return 0;
}
 
/* Implementation specific.
   Set destination operand (register direct, register indirect
   (with displacement) with value. */
 
void set_operand(char *dstoperand, unsigned long value)
{
	char operand[OPERANDNAME_LEN];
 
	debug("set_operand %s <= %u\n", dstoperand, value);
	strcpy(operand, dstoperand);
 
	if (*operand == '#') {		/* immediate */
		printf("INTERNAL ERROR: Can't set immediate operand.\n");
		cont_run = 0;
	}
	else
	if (!strstr(operand, "(")) 	/* not indirect but ...*/
		if (*operand == 'r') 	/* ... register direct */
			set_reg32(operand, value);
		else {			/* ... rel. or abs. address */
			/* printf("INTERNAL ERROR: Can't set addr operand.\n"); 
			cont_run = 0; */
			set_mem32(eval_label(operand), value);
		}
	else {				/* register indirect */
		int disp;		/* with possible displacement */
		char *regstr;
		unsigned int memaddr;
 
		disp = atoi(operand);	/* operand == "nn(rXX)" */
		regstr = strstr(operand, "(r") + 1;	/* regstr == "rXX)" */
		*strstr(regstr, ")") = '\0';		/* regstr == "rXX" */
		memaddr = eval_reg(regstr) + disp;
 
		set_mem32(memaddr, value);
	}
 
	return;
}
 
void reset()
{
	cycles = 0;
	supercycles = 0;
	memset(reg, 0, sizeof(reg));
	memset(iqueue, 0, sizeof(iqueue));
	memset(icomplet, 0, sizeof(icomplet));
	pctemp = eval_label("_main");
	pc = pctemp;
	debug("reset ...");
	set_reg32(STACK_REG, MEMORY_LEN - STACK_SIZE);
}
 
void fetch()
{
	/* Cycles after reset. */
	cycles++;
 
	/* Fetch instruction. */
	strcpy(iqueue[0].insn, mem[pc].insn);
	strcpy(iqueue[0].op1, mem[pc].op1);
	strcpy(iqueue[0].op2, mem[pc].op2);
	strcpy(iqueue[0].op3, mem[pc].op3);
	strcpy(iqueue[0].op4, mem[pc].op4);
	iqueue[0].insn_addr = pc;
	iqueue[0].dependdst = NULL;
	iqueue[0].dependsrc1 = NULL;
	iqueue[0].dependsrc2 = NULL;
 
	/* Increment program counter. */
	pc = pctemp;
	pctemp += 4;
 
	/* Check for breakpoint. */
	if (mem[pc].brk)
		cont_run = 0;	/* Breakpoint set. */
 
	return;
}
 
void decode(struct iqueue_entry *cur)
{
 
	cur->dependdst = cur->op1;
	cur->dependsrc1 = cur->op2;	/* for calculating register */
	cur->dependsrc2 = cur->op3;	/* dependency */
 
	cur->func_unit = unknown;
 
	if (strcmp(cur->insn, "l.stor32") == 0) {
		cur->func_unit = store;
		set_operand(cur->op1, eval_operand(cur->op2));
	} else
	if (strcmp(cur->insn, "h.stor32") == 0) {
		cur->func_unit = store;
		set_operand(cur->op1, eval_operand(cur->op2));
	} else
	if (strcmp(cur->insn, "l.stor8") == 0) {
		cur->func_unit = store;
		set_operand(cur->op1, (eval_operand(cur->op2) << 24) + (eval_operand(cur->op1) & 0xffffff));
	} else
	if (strcmp(cur->insn, "l.stor16") == 0) {
		cur->func_unit = store;
		set_operand(cur->op1, (eval_operand(cur->op2) << 16) + (eval_operand(cur->op1) & 0xffff));
	} else
	if (strcmp(cur->insn, "l.load32u") == 0) {
		cur->func_unit = load;
		set_operand(cur->op1, eval_operand(cur->op2));
	} else
	if (strcmp(cur->insn, "h.load32u") == 0) {
		cur->func_unit = load;
		set_operand(cur->op1, eval_operand(cur->op2));
	} else
	if (strcmp(cur->insn, "l.load8s") == 0) {
		signed char temp = (eval_operand(cur->op2) >> 24);
		cur->func_unit = load;
		set_operand(cur->op1, temp);
	} else
	if (strcmp(cur->insn, "l.load8u") == 0) {
		unsigned char temp = (eval_operand(cur->op2) >> 24);
		cur->func_unit = load;
		set_operand(cur->op1, temp);
	} else
	if (strcmp(cur->insn, "l.load16s") == 0) {
		signed short temp = (eval_operand(cur->op2) >> 16);
		cur->func_unit = load;
		set_operand(cur->op1, temp);
	} else
	if (strcmp(cur->insn, "l.load16u") == 0) {
		unsigned short temp = (eval_operand(cur->op2) >> 16);
		cur->func_unit = load;
		set_operand(cur->op1, temp);
	} else
 	if (strcmp(cur->insn, "l.immlo16u") == 0) {
		cur->func_unit = movimm;
		set_operand(cur->op1, (eval_operand(cur->op1) & 0xffff0000) | eval_operand(cur->op2));
	} else
	if (strcmp(cur->insn, "l.immhi16u") == 0) {
		cur->func_unit = movimm;
		set_operand(cur->op1, (eval_operand(cur->op1) & 0xffff) | (eval_operand(cur->op2) << 16));
	} else
	if (strcmp(cur->insn, "h.immch32s") == 0) {
		cur->func_unit = movimm;
		set_operand(cur->op1, (signed)eval_operand(cur->op2));
	} else
 	if (strcmp(cur->insn, "h.mov32") == 0) {
		cur->func_unit = move;
		set_operand(cur->op1, eval_operand(cur->op2));
	} else
	if (strcmp(cur->insn, "l.and32") == 0) {
		cur->func_unit = arith;
		set_operand(cur->op1, eval_operand(cur->op2) & eval_operand(cur->op3));
	} else
	if (strcmp(cur->insn, "l.or32") == 0) {
		cur->func_unit = arith;
		set_operand(cur->op1, eval_operand(cur->op2) | eval_operand(cur->op3));
	} else
	if (strcmp(cur->insn, "l.xor32") == 0) {
		cur->func_unit = arith;
		set_operand(cur->op1, eval_operand(cur->op2) ^ eval_operand(cur->op3));
	} else
	if (strcmp(cur->insn, "l.xori16") == 0) {
		cur->func_unit = arith;
		set_operand(cur->op1, eval_operand(cur->op2) ^ (eval_operand(cur->op3) & 0xffff));
	} else
	if (strcmp(cur->insn, "h.ext16s") == 0) {
		cur->func_unit = extend;
		if ((eval_operand(cur->op1) & 0x8000) == 0x8000)
			set_operand(cur->op1, eval_operand(cur->op1) | 0xffff0000);
		else
			set_operand(cur->op1, eval_operand(cur->op1) & 0x0000ffff);
	} else
	if (strcmp(cur->insn, "h.ext8s") == 0) {
		cur->func_unit = extend;
		if ((eval_operand(cur->op1) & 0x80) == 0x80)
			set_operand(cur->op1, eval_operand(cur->op1) | 0xffffff00);
		else
			set_operand(cur->op1, eval_operand(cur->op1) & 0x000000ff);
	} else
	if (strcmp(cur->insn, "h.ext16z") == 0) {
		cur->func_unit = extend;
		set_operand(cur->op1, eval_operand(cur->op1) & 0x0000ffff);
	} else
	if (strcmp(cur->insn, "h.ext8z") == 0) {
		cur->func_unit = extend;
		set_operand(cur->op1, eval_operand(cur->op1) & 0x000000ff);
	} else
	if (strcmp(cur->insn, "h.add32s") == 0) {
		signed long temp3, temp2, temp1;
		signed char temp4;
 
		cur->func_unit = arith;
		temp3 = eval_operand(cur->op3);
		temp2 = eval_operand(cur->op2);
		temp1 = temp2 + temp3;
		set_operand(cur->op1, temp1);
 
		temp4 = temp1;
		if (temp4 == temp1)
			mstats.byteadd++;
	} else
	if (strcmp(cur->insn, "l.addi32s") == 0) {
		signed long temp3, temp2, temp1;
		signed char temp4;
 
		cur->func_unit = arith;
		temp3 = eval_operand(cur->op3);
		temp2 = eval_operand(cur->op2);
		temp1 = temp2 + temp3;
		set_operand(cur->op1, temp1);
 
		temp4 = temp1;
		if (temp4 == temp1)
			mstats.byteadd++;
	} else
	if (strcmp(cur->insn, "l.sub32s") == 0) {
		signed long temp3, temp2, temp1;
 
		cur->func_unit = arith;
		temp3 = eval_operand(cur->op3);
		temp2 = eval_operand(cur->op2);
		temp1 = temp2 - temp3;
		set_operand(cur->op1, temp1);
	} else
	if (strcmp(cur->insn, "l.subi32s") == 0) {
		signed long temp3, temp2, temp1;
 
		cur->func_unit = arith;
		temp3 = eval_operand(cur->op3);
		temp2 = eval_operand(cur->op2);
		temp1 = temp2 - temp3;
		set_operand(cur->op1, temp1);
	} else
	if (strcmp(cur->insn, "l.mul32s") == 0) {
		signed long temp3, temp2, temp1;
 
		cur->func_unit = arith;
		temp3 = eval_operand(cur->op3);
		temp2 = eval_operand(cur->op2);
		temp1 = temp2 * temp3;
		set_operand(cur->op1, temp1);
	} else
	if (strcmp(cur->insn, "l.div32s") == 0) {
		signed long temp3, temp2, temp1;
 
		cur->func_unit = arith;
		temp3 = eval_operand(cur->op3);
		temp2 = eval_operand(cur->op2);
		temp1 = temp2 / temp3;
		set_operand(cur->op1, temp1);
	} else
	if (strcmp(cur->insn, "l.div32u") == 0) {
		unsigned long temp3, temp2, temp1;
 
		cur->func_unit = arith;
		temp3 = eval_operand(cur->op3);
		temp2 = eval_operand(cur->op2);
		temp1 = temp2 / temp3;
		set_operand(cur->op1, temp1);
	} else
	if (strcmp(cur->insn, "l.shla32") == 0) {
		int sign = 1;
		cur->func_unit = shift;
		debug("shla: op3:%d op4:%d", eval_operand(cur->op3), eval_operand(cur->op4));
		debug("shla: op4=%s", cur->op4);
		if ((signed)eval_operand(cur->op2) < 0)
			sign = -1;
		set_operand(cur->op1, eval_operand(cur->op2) << (eval_operand(cur->op3) | eval_operand(cur->op4)));
		set_operand(cur->op1, eval_operand(cur->op1) * sign);
	} else
	if (strcmp(cur->insn, "l.shra32") == 0) {
		int sign = 1;
		cur->func_unit = shift;
 
		if ((signed)eval_operand(cur->op2) < 0)
			sign = -1;
		set_operand(cur->op1, eval_operand(cur->op2) >> (eval_operand(cur->op3) | eval_operand(cur->op4)));
		set_operand(cur->op1, eval_operand(cur->op1) * sign);
	} else
	if (strcmp(cur->insn, "l.shrl32") == 0) {
		cur->func_unit = shift;
		set_operand(cur->op1, eval_operand(cur->op2) >> eval_operand(cur->op3));
	} else
	if (strcmp(cur->insn, "l.jmp") == 0) {
		cur->func_unit = jump;
		pctemp = eval_operand(cur->op1);
	} else
	if (strcmp(cur->insn, "l.jal") == 0) {
		cur->func_unit = jump;
		pctemp = eval_operand(cur->op1);
                set_reg32(LINK_REG, pc + 4);
	} else
	if (strcmp(cur->insn, "h.jalr") == 0) {
		cur->func_unit = jump;
		pctemp = eval_operand(cur->op1);
                set_reg32(LINK_REG, pc + 4);
	} else
	if (strcmp(cur->insn, "jr") == 0) {
		cur->func_unit = jump;
		cur->dependsrc1 = cur->op1;
		pctemp = eval_operand(cur->op1);
	} else
	if (strcmp(cur->insn, "h.nop") == 0) {
		cur->func_unit = nop;	
	} else
	if (strcmp(cur->insn, "l.bfeqz") == 0) {
		cur->func_unit = branch;
		cur->dependsrc1 = ccr_flag;		
		if (flag == 0) {
			pctemp = eval_operand(cur->op1);
			mstats.beqz.taken++;
			bpb_update(cur->insn_addr, 1);
			btic_update(pctemp);
		} else {
			mstats.beqz.nottaken++;
			bpb_update(cur->insn_addr, 0);
			btic_update(pc);
		}
	} else
	if (strcmp(cur->insn, "l.bfnez") == 0) {
		cur->func_unit = branch;
		cur->dependsrc1 = ccr_flag;
		if (flag) {
			pctemp = eval_operand(cur->op1);
			mstats.bnez.taken++;
			bpb_update(cur->insn_addr, 1);
			btic_update(pctemp);
		} else {
			mstats.bnez.nottaken++;
			bpb_update(cur->insn_addr, 0);
			btic_update(pc);
		}
	} else
	if (strcmp(cur->insn, "h.sfeq32") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = eval_operand(cur->op1) == eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sfne32") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = eval_operand(cur->op1) != eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sfgt32s") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (signed)eval_operand(cur->op1) >
		       (signed)eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sfge32s") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (signed)eval_operand(cur->op1) >=
		       (signed)eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sflt32s") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (signed)eval_operand(cur->op1) <
		       (signed)eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sfle32s") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (signed)eval_operand(cur->op1) <=
		       (signed)eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sfgt32u") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (unsigned)eval_operand(cur->op1) >
		       (unsigned)eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sfge32u") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (unsigned)eval_operand(cur->op1) >=
		       (unsigned) eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sflt32u") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (unsigned)eval_operand(cur->op1) <
		       (unsigned)eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "h.sfle32u") == 0) {
		cur->func_unit = compare;
		cur->dependsrc2 = cur->op1;
		cur->dependdst = ccr_flag;
		flag = (unsigned)eval_operand(cur->op1) <=
		       (unsigned)eval_operand(cur->op2);
	} else
	if (strcmp(cur->insn, "simrdtsc") == 0) {
		set_operand(cur->op1, supercycles);
	} else
	if (strcmp(cur->insn, "simprintf") == 0) {
		unsigned long stackaddr, fmtaddr, args;
 
		stackaddr = eval_reg(FRAME_REG);
		simprintf(stackaddr, eval_reg("r3"));
		debug("simprintf %x %x %x\n", stackaddr, fmtaddr, args);
	} else {
		printf("\nEXCEPTION: illegal opcode %s ", cur->insn);
		printf("at %.8lx\n", cur->insn_addr);
		cont_run = 0;
	}
 
	/* Dynamic, dependency stats. */
	adddstats(icomplet[0].insn, iqueue[0].insn, 1, check_depend());
 
	/* Dynamic, functional units stats. */
	addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend());
 
	/* Dynamic, single stats. */
	addsstats(iqueue[0].insn, 1, 0);
 
	/* Pseudo multiple issue benchmark */
	if ((multissue[cur->func_unit] == 0) || (check_depend())) {
		int i;
		for (i = 0; i < 20; i++)
			multissue[i] = 1;
		supercycles++;
		/* if (check_depend())
			supercycles++; */
		multissue[move] = 2;
		multissue[movimm] = 2;
		multissue[arith] = 3;
		multissue[store] = 4;
		multissue[load] = 2;
	}
	multissue[cur->func_unit]--;
 
	return;
}
 
void execute()
{
	int i;
 
	/* Here comes real execution someday... */
 
	/* Instruction waits in completition buffer until retired. */
	strcpy(icomplet[0].insn, iqueue[0].insn);
	strcpy(icomplet[0].op1, iqueue[0].op1);
	strcpy(icomplet[0].op2, iqueue[0].op2);
	strcpy(icomplet[0].op3, iqueue[0].op3);
	strcpy(icomplet[0].op4, iqueue[0].op4);
	icomplet[0].func_unit = iqueue[0].func_unit;	
	icomplet[0].insn_addr = iqueue[0].insn_addr;
 
	if (iqueue[0].dependdst == iqueue[0].op1)
		icomplet[0].dependdst = icomplet[0].op1;
	else
	if (iqueue[0].dependdst == iqueue[0].op2)
		icomplet[0].dependdst = icomplet[0].op2;
	else
	if (iqueue[0].dependdst == iqueue[0].op3)
		icomplet[0].dependdst = icomplet[0].op3;
	else
		icomplet[0].dependdst = NULL;
 
	if (iqueue[0].dependsrc1 == iqueue[0].op1)
		icomplet[0].dependsrc1 = icomplet[0].op1;
	else
	if (iqueue[0].dependsrc1 == iqueue[0].op2)
		icomplet[0].dependsrc1 = icomplet[0].op2;
	else
	if (iqueue[0].dependsrc1 == iqueue[0].op3)
		icomplet[0].dependsrc1 = icomplet[0].op3;
	else
		icomplet[0].dependsrc1 = NULL;
 
	if (iqueue[0].dependsrc2 == iqueue[0].op1)
		icomplet[0].dependsrc2 = icomplet[0].op1;
	else
	if (iqueue[0].dependsrc2 == iqueue[0].op2)
		icomplet[0].dependsrc2 = icomplet[0].op2;
	else
	if (iqueue[0].dependsrc2 == iqueue[0].op3)
		icomplet[0].dependsrc2 = icomplet[0].op3;
	else
		icomplet[0].dependsrc2 = NULL;
 
	/* History of execution */
	for (i = HISTEXEC_LEN - 1; i; i--)
		histexec[i] = histexec[i - 1];
	histexec[0] = icomplet[0].insn_addr;	/* add last insn */
 
	return;
}
 
void dumpreg()
{
	int i;
 
	printf("\n\nIQ[0]:");
	dumpmemory(iqueue[0].insn_addr, iqueue[0].insn_addr + 4);
	printf(" (just executed)\tCYCLE: %u \tSUPERCYCLE: %u\nPC:", cycles, supercycles);
	dumpmemory(pc, pc + 4);
	printf(" (next insn)");
	for(i = 0; i < MAX_GPRS; i++) {
		if (i % 4 == 0)
			printf("\n");
		printf("GPR%.2u: %.8lx  ", i, reg[i]);
	}
	printf("flag: %u\n", flag);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.