OpenCores
no use no use 1/1 no use no use
[or1ksim #6] Remove global op variable
by Unknown on Jan 25, 2005
Not available!
Hi, This patch removes the global op structure and all the administration that comes with it. This patch has a noticable speed improvement when booting linux, though it is only slight. I have basically rewritten depend_operands. It was basically useless. Among others the last operand would never have been checked. I have again modified or32.c to set the OPTYPE_DIS flag on all the operands that are part of the immediate value and not just the last. I have checked and this change does not break anything in gdb or binutils. ChangeLog: * Remove the global op structure. nog. -------------- next part -------------- --- cpu/or32/execute.c 2005-01-25 19:04:57.000000000 +0100 +++ ../or1ksim-ac/cpu/or32/execute.c 2005-01-25 20:56:50.000000000 +0100 @@ -1,5 +1,6 @@ /* execute.c -- OR1K architecture dependent simulation Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + Copyright (C) 2005 Gy?rgy `nog' Jeney, nog@sdf.lonestar.org This file is part of OpenRISC 1000 Architectural Simulator. @@ -102,8 +103,10 @@ /* Local data needed for execution. */ static int next_delay_insn; static int breakpoint; -static unsigned long *op; -static int num_op; + +/* Effective address of instructions that have an effective address. This is + * only used to get dump_exe_log correct */ +static unsigned long insn_ea; /* Implementation specific. Get an actual value of a specific register. */ @@ -182,7 +185,34 @@ } } -/* Does srcoperand depend on computation of dstoperand? Return +/* Implementation specific. + Evaluates source operand opd. */ + +static unsigned long eval_operand_val(unsigned long insn, + struct insn_op_struct *opd) +{ + unsigned long operand = 0; + unsigned long sbit; + unsigned int nbits = 0; + + while(1) { + operand |= ((insn >> (opd->type & OPTYPE_SHR)) & ((1 data) - 1)) data; + + if(opd->type & OPTYPE_OP) + break; + opd++; + } + + if(opd->type & OPTYPE_SIG) { + sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR; + if(operand & (1 insn_index].flags & OR32_W_FLAG && or32_opcodes[next->insn_index].flags & OR32_R_FLAG) return 1; - while (!(prev->op[i + MAX_OPERANDS] & OPTYPE_LAST)) - if (prev->op[i + MAX_OPERANDS] & OPTYPE_DST) - { - type = prev->op[i + MAX_OPERANDS]; - break; - } - else - i++; + opd = op_start[prev->insn_index]; + prev_dis = 0; + + while (1) { + if (opd->type & OPTYPE_DIS) + prev_dis = 1; + + if (opd->type & OPTYPE_DST) { + type = opd->type; + if (prev_dis) + type |= OPTYPE_DIS; + /* Destination is always a register */ + prev_reg_val = eval_operand_val (prev->insn, opd); + break; + } + if (opd->type & OPTYPE_LAST) + return 0; /* Doesn't have a destination operand */ + if (opd->type & OPTYPE_OP) + prev_dis = 0; + opd++; + } /* We search all source operands - if we find confict => return 1 */ - i = 0; - while (!(next->op[i + MAX_OPERANDS] & OPTYPE_LAST)) - if (!(next->op[i + MAX_OPERANDS] & OPTYPE_DST)) - { - if (next->op[i + MAX_OPERANDS] & OPTYPE_DIS) { - if (type & OPTYPE_DIS) - return 1; - else if (next->op == prev->op - && (next->op[i + MAX_OPERANDS] & OPTYPE_REG)) - return 1; - } - if (next->op == prev->op - && (next->op[i + MAX_OPERANDS] & OPTYPE_REG) - && (type & OPTYPE_REG)) + opd = op_start[next->insn_index]; + next_dis = 0; + + while (1) { + if (opd->type & OPTYPE_DIS) + next_dis = 1; + /* This instruction sequence also depends on order of execution: + * l.lw r1, k(r1) + * l.sw k(r1), r4 + * Here r1 is a destination in l.sw */ + /* FIXME: This situation is not handeld here when r1 == r2: + * l.sw k(r1), r4 + * l.lw r3, k(r2) + */ + if (!(opd->type & OPTYPE_DST) || (next_dis && (opd->type & OPTYPE_DST))) { + if (opd->type & OPTYPE_REG) + if (eval_operand_val (next->insn, opd) == prev_reg_val) return 1; - i++; - } - else - i++; + } + if (opd->type & OPTYPE_LAST) + break; + opd++; + } + return 0; } @@ -427,18 +478,26 @@ /* Outputs dissasembled instruction */ void dump_exe_log () { - unsigned long i = iqueue[0].insn_addr; + unsigned long insn_addr = iqueue[0].insn_addr; + unsigned long i, j; - if (i == 0xffffffff) return; - if (config.sim.exe_log_start name); } if (config.sim.exe_log_type == EXE_LOG_SOFTWARE) { - int i,j=0; + struct insn_op_struct *opd = op_start[iqueue[0].insn_index]; - for (i = 0; i type & OPTYPE_OP)) + opd++; + if (opd->type & OPTYPE_DIS) { + fprintf (runtime.sim.fexe_log, "EA =%08lx PA =%08lx ", insn_ea, + peek_into_dtlb(insn_ea,0,0)); + opd++; /* Skip of register operand */ + j++; + } else if ((opd->type & OPTYPE_REG) && i) { + fprintf (runtime.sim.fexe_log, "r%-2li=%08lx ", i, + evalsim_reg32 (i)); } else fprintf (runtime.sim.fexe_log, " "); - - i+=j; - for (; i type & OPTYPE_LAST) + break; + opd++; + } + while(j > (opd->type & OPTYPE_SHR)) & ((1 data) - 1)) data; - if (opd->type & OPTYPE_OP) - break; - opd++; - } + unsigned long ret; - /* Do we have to sign extend? */ - if (opd->type & OPTYPE_SIG) - { - int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR; - if (tmp & (1 type & OPTYPE_DIS) { - /* We have to read register later. */ - data += tmp; - dis = 1; - } else - { - if (dis && (opd->type & OPTYPE_REG)) - op[no] = data + eval_reg32 (tmp); - else - op[no] = tmp; - op[no + MAX_OPERANDS] = opd->type | (dis ? OPTYPE_DIS : 0); - no++; - data = 0; - dis = 0; - } - if(opd->type & OPTYPE_LAST) { - num_op = no; - return; - } - opd++; + while (op_no) { + if(opd->type & OPTYPE_LAST) { + fprintf (stderr, "Instruction requested more operands than it has\n"); + exit (1); } - num_op = no; -} - -/* Implementation specific. - Evaluates source operand op_no. */ + if((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS)) + op_no--; + opd++; + } -static unsigned long eval_operand (int op_no) -{ - if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) { - return op[op_no]; - } else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) { - return eval_reg32 (op[op_no]); - } else { - return op[op_no]; + if (opd->type & OPTYPE_DIS) { + ret = eval_operand_val (insn, opd); + while (!(opd->type & OPTYPE_OP)) + opd++; + opd++; + ret += eval_reg32 (eval_operand_val (insn, opd)); + insn_ea = ret; + return ret; } + if (opd->type & OPTYPE_REG) + return eval_reg32 (eval_operand_val (insn, opd)); + + return eval_operand_val (insn, opd); } /* Implementation specific. Set destination operand (reister direct) with value. */ -inline static void set_operand(int op_no, unsigned long value) +inline static void set_operand(int op_no, unsigned long value, + unsigned long insn_index, unsigned long insn) { - /* Mark this as destination operand. */ - if (!(op[op_no + MAX_OPERANDS] & OPTYPE_REG)) { + struct insn_op_struct *opd = op_start[insn_index]; + + while (op_no) { + if(opd->type & OPTYPE_LAST) { + fprintf (stderr, "Instruction requested more operands than it has\n"); + exit (1); + } + if((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS)) + op_no--; + opd++; + } + + if (!(opd->type & OPTYPE_REG)) { fprintf (stderr, "Trying to set a non-register operand\n"); exit (1); } - set_reg32(op[op_no], value); + set_reg32 (eval_operand_val (insn, opd), value); } /* Simple and rather slow decoding function based on built automata. */ @@ -720,18 +767,16 @@ if (insn_index op[0]; - eval_operands (current->insn, insn_index, &breakpoint); or32_opcodes[insn_index].exec(current); } if (do_stats) analysis(&iqueue[0]); } -#define SET_PARAM0(val) set_operand(0, val) +#define SET_PARAM0(val) set_operand(0, val, current->insn_index, current->insn) -#define PARAM0 eval_operand(0) -#define PARAM1 eval_operand(1) -#define PARAM2 eval_operand(2) +#define PARAM0 eval_operand(0, current->insn_index, current->insn) +#define PARAM1 eval_operand(1, current->insn_index, current->insn) +#define PARAM2 eval_operand(2, current->insn_index, current->insn) #include "insnset.c" --- cpu/or32/or32.c 2005-01-25 19:04:57.000000000 +0100 +++ ../or1ksim-ac/cpu/or32/or32.c 2005-01-25 18:06:11.000000000 +0100 @@ -860,6 +857,7 @@ { char *args = opcode->args; int i, type; + int num_cur_op = 0;; i = 0; type = 0; @@ -892,6 +890,7 @@ type |= ((num_ones (arg) - 1) type, cur->data); cur++; + num_cur_op++; } args++; } else if (*args == '(') { /* Next param is displacement. Later we will treat them as one operand. */ - cur--; - cur->type = type | cur->type | OPTYPE_DIS | OPTYPE_OP; + /* Set the OPTYPE_DIS flag on all insn_op_structs that belong to this + * operand */ + while(num_cur_op > 0) { + cur[-num_cur_op].type |= type | OPTYPE_DIS; + num_cur_op--; + } + cur[-1].type |= OPTYPE_OP; debug(9, ">%08X %08X\n", cur->type, cur->data); - cur++; type = 0; i++; args++; --- cpu/or32/generate.c 2005-01-25 08:50:59.000000000 +0100 +++ ../or1ksim-ac/cpu/or32/generate.c 2005-01-25 21:04:32.000000000 +0100 @@ -30,7 +30,6 @@ static char *in_file; static char *out_file; -static unsigned long op[MAX_OPERANDS]; /* Whether this instruction stores something in register */ static int write_to_reg; @@ -129,8 +128,7 @@ return 0; } -/* Parses and puts operands into op[] structure. - Replacement for eval_operands routine. */ +/* Parses operands. */ static int gen_eval_operands (FILE *fo, int insn_index, int level) @@ -142,6 +140,7 @@ int set_param = 0; int dis = 0; int sbit; + int dis_op = -1; write_to_reg = 0; @@ -188,7 +187,7 @@ nbits += opd->data; - if (opd->type & OPTYPE_DIS) { + if ((opd->type & OPTYPE_DIS) && (opd->type & OPTYPE_OP)) { sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR; if (opd->type & OPTYPE_SIG) shift_fprintf (level, fo, "if(%c & 0x%08x) %c |= 0x%x;\n", @@ -199,6 +198,7 @@ 'a' + num_ops, opd->type & OPTYPE_SHR, (1 data) - 1); dis = 1; + dis_op = num_ops; } if (opd->type & OPTYPE_OP) { @@ -220,10 +220,6 @@ shift_fprintf (level, fo, "#define PARAM%i %c\n", num_ops, 'a' + num_ops); } - - op[num_ops] = opd->type; - if(dis) - op[num_ops] |= OPTYPE_DIS; num_ops++; nbits = 0; dis = 0; @@ -243,39 +239,33 @@ for (i = 0; i = 0) - num_op = gen_eval_operands (fo, index, level); - else - num_op = 0; + dis_op = gen_eval_operands (fo, index, level); if (index op[0];\n"); + if (dis_op >= 0) + shift_fprintf (level, fo, "insn_ea = %c;\n", 'a' + dis_op); + shift_fprintf (level, fo, "current->insn_index = %i; /* \"%s\" */\n", index, insn_name (index)); - for (i = 0; i
no use no use 1/1 no use no use
© copyright 1999-2026 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.