diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:35:26 +0000 |
commit | c906108c21474dfb4ed285bcc0ac6fe02cd400cc (patch) | |
tree | a0015aa5cedc19ccbab307251353a41722a3ae13 /sim/common/cgen-utils.c | |
parent | cd946cff9ede3f30935803403f06f6ed30cad136 (diff) | |
download | gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.zip gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.gz gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.bz2 |
Initial creation of sourceware repositorygdb-4_18-branchpoint
Diffstat (limited to 'sim/common/cgen-utils.c')
-rw-r--r-- | sim/common/cgen-utils.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/sim/common/cgen-utils.c b/sim/common/cgen-utils.c new file mode 100644 index 0000000..2faff5c --- /dev/null +++ b/sim/common/cgen-utils.c @@ -0,0 +1,328 @@ +/* Support code for various pieces of CGEN simulators. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Contributed by Cygnus Support. + +This file is part of GDB, the GNU debugger. + +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, 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., +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sim-main.h" +#include "dis-asm.h" + +#define MEMOPS_DEFINE_INLINE +#include "cgen-mem.h" + +#define SEMOPS_DEFINE_INLINE +#include "cgen-ops.h" + +#undef min +#define min(a,b) ((a) < (b) ? (a) : (b)) + +const char *mode_names[] = { + "VM", + "BI", + "QI", + "HI", + "SI", + "DI", + "UQI", + "UHI", + "USI", + "UDI", + "SF", + "DF", + "XF", + "TF", + 0, /* MODE_TARGET_MAX */ + "INT", + "UINT", + "PTR" +}; + +/* Opcode table for virtual insns used by the simulator. */ + +#define V CGEN_ATTR_MASK (CGEN_INSN_VIRTUAL) + +static const CGEN_IBASE virtual_insn_entries[] = +{ + { + VIRTUAL_INSN_X_INVALID, "--invalid--", NULL, 0, + { CGEN_INSN_NBOOL_ATTRS, V, { 0 } } + }, + { + VIRTUAL_INSN_X_BEFORE, "--before--", NULL, 0, + { CGEN_INSN_NBOOL_ATTRS, V, { 0 } } + }, + { + VIRTUAL_INSN_X_AFTER, "--after--", NULL, 0, + { CGEN_INSN_NBOOL_ATTRS, V, { 0 } } + }, + { + VIRTUAL_INSN_X_BEGIN, "--begin--", NULL, 0, + { CGEN_INSN_NBOOL_ATTRS, V, { 0 } } + }, + { + VIRTUAL_INSN_X_CHAIN, "--chain--", NULL, 0, + { CGEN_INSN_NBOOL_ATTRS, V, { 0 } } + }, + { + VIRTUAL_INSN_X_CTI_CHAIN, "--cti-chain--", NULL, 0, + { CGEN_INSN_NBOOL_ATTRS, V, { 0 } } + } +}; + +#undef V + +const CGEN_INSN cgen_virtual_insn_table[] = +{ + { & virtual_insn_entries[0] }, + { & virtual_insn_entries[1] }, + { & virtual_insn_entries[2] }, + { & virtual_insn_entries[3] }, + { & virtual_insn_entries[4] }, + { & virtual_insn_entries[5] } +}; + +/* Initialize cgen things. + This is called after sim_post_argv_init. */ + +void +cgen_init (SIM_DESC sd) +{ + int i, c; + + /* If no profiling or tracing has been enabled, run in fast mode. */ + { + int run_fast_p = 1; + + for (c = 0; c < MAX_NR_PROCESSORS; ++c) + { + SIM_CPU *cpu = STATE_CPU (sd, c); + + for (i = 0; i < MAX_PROFILE_VALUES; ++i) + if (CPU_PROFILE_FLAGS (cpu) [i]) + { + run_fast_p = 0; + break; + } + for (i = 0; i < MAX_TRACE_VALUES; ++i) + if (CPU_TRACE_FLAGS (cpu) [i]) + { + run_fast_p = 0; + break; + } + if (! run_fast_p) + break; + } + STATE_RUN_FAST_P (sd) = run_fast_p; + } +} + +/* Return the name of insn number I. */ + +const char * +cgen_insn_name (SIM_CPU *cpu, int i) +{ + return CGEN_INSN_NAME ((* CPU_GET_IDATA (cpu)) ((cpu), (i))); +} + +/* Return the maximum number of extra bytes required for a SIM_CPU struct. */ + +int +cgen_cpu_max_extra_bytes (void) +{ + int i; + int extra = 0; + + for (i = 0; sim_machs[i] != 0; ++i) + { + int size = IMP_PROPS_SIM_CPU_SIZE (MACH_IMP_PROPS (sim_machs[i])); + if (size > extra) + extra = size; + } + return extra; +} + +#ifdef DI_FN_SUPPORT + +DI +make_struct_di (hi, lo) + SI hi, lo; +{ + DI result; + + result.hi = hi; + result.lo = lo; + return result; +} + +DI +ANDDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + SI alo = GETLODI (a); + SI bhi = GETHIDI (b); + SI blo = GETLODI (b); + return MAKEDI (ahi & bhi, alo & blo); +} + +DI +ORDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + SI alo = GETLODI (a); + SI bhi = GETHIDI (b); + SI blo = GETLODI (b); + return MAKEDI (ahi | bhi, alo | blo); +} + +DI +ADDDI (a, b) + DI a, b; +{ + USI ahi = GETHIDI (a); + USI alo = GETLODI (a); + USI bhi = GETHIDI (b); + USI blo = GETLODI (b); + USI x = alo + blo; + return MAKEDI (ahi + bhi + (x < alo), x); +} + +DI +MULDI (a, b) + DI a, b; +{ + USI ahi = GETHIDI (a); + USI alo = GETLODI (a); + USI bhi = GETHIDI (b); + USI blo = GETLODI (b); + USI rhi,rlo; + USI x0, x1, x2, x3; + + x0 = alo * blo; + x1 = alo * bhi; + x2 = ahi * blo; + x3 = ahi * bhi; + +#define SI_TYPE_SIZE 32 +#define BITS4 (SI_TYPE_SIZE / 4) +#define ll_B (1L << (SI_TYPE_SIZE / 2)) +#define ll_lowpart(t) ((USI) (t) % ll_B) +#define ll_highpart(t) ((USI) (t) / ll_B) + x1 += ll_highpart (x0); /* this can't give carry */ + x1 += x2; /* but this indeed can */ + if (x1 < x2) /* did we get it? */ + x3 += ll_B; /* yes, add it in the proper pos. */ + + rhi = x3 + ll_highpart (x1); + rlo = ll_lowpart (x1) * ll_B + ll_lowpart (x0); + return MAKEDI (rhi + (alo * bhi) + (ahi * blo), rlo); +} + +DI +SHLDI (val, shift) + DI val; + SI shift; +{ + USI hi = GETHIDI (val); + USI lo = GETLODI (val); + /* FIXME: Need to worry about shift < 0 || shift >= 32. */ + return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); +} + +DI +SLADI (val, shift) + DI val; + SI shift; +{ + SI hi = GETHIDI (val); + USI lo = GETLODI (val); + /* FIXME: Need to worry about shift < 0 || shift >= 32. */ + return MAKEDI ((hi << shift) | (lo >> (32 - shift)), lo << shift); +} + +DI +SRADI (val, shift) + DI val; + SI shift; +{ + SI hi = GETHIDI (val); + USI lo = GETLODI (val); + /* We use SRASI because the result is implementation defined if hi < 0. */ + /* FIXME: Need to worry about shift < 0 || shift >= 32. */ + return MAKEDI (SRASI (hi, shift), (hi << (32 - shift)) | (lo >> shift)); +} + +int +GEDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + USI alo = GETLODI (a); + SI bhi = GETHIDI (b); + USI blo = GETLODI (b); + if (ahi > bhi) + return 1; + if (ahi == bhi) + return alo >= blo; + return 0; +} + +int +LEDI (a, b) + DI a, b; +{ + SI ahi = GETHIDI (a); + USI alo = GETLODI (a); + SI bhi = GETHIDI (b); + USI blo = GETLODI (b); + if (ahi < bhi) + return 1; + if (ahi == bhi) + return alo <= blo; + return 0; +} + +DI +CONVHIDI (val) + HI val; +{ + if (val < 0) + return MAKEDI (-1, val); + else + return MAKEDI (0, val); +} + +DI +CONVSIDI (val) + SI val; +{ + if (val < 0) + return MAKEDI (-1, val); + else + return MAKEDI (0, val); +} + +SI +CONVDISI (val) + DI val; +{ + return GETLODI (val); +} + +#endif /* DI_FN_SUPPORT */ |