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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/tags/gdb/gdb-6.8/gdb-6.8.openrisc-2.1/sim/v850
    from Rev 24 to Rev 33
    Reverse comparison

Rev 24 → Rev 33

/sim-main.h
0,0 → 1,390
#ifndef SIM_MAIN_H
#define SIM_MAIN_H
 
/* General config options */
 
#define WITH_CORE
#define WITH_MODULO_MEMORY 1
#define WITH_WATCHPOINTS 1
 
 
/* The v850 has 32bit words, numbered 31 (MSB) to 0 (LSB) */
 
#define WITH_TARGET_WORD_MSB 31
 
 
#include "sim-basics.h"
#include "sim-signal.h"
 
typedef address_word sim_cia;
 
#include "sim-base.h"
 
#include "simops.h"
#include "bfd.h"
 
 
typedef signed8 int8;
typedef unsigned8 uint8;
typedef signed16 int16;
typedef unsigned16 uint16;
typedef signed32 int32;
typedef unsigned32 uint32;
typedef unsigned32 reg_t;
 
 
/* The current state of the processor; registers, memory, etc. */
 
typedef struct _v850_regs {
reg_t regs[32]; /* general-purpose registers */
reg_t sregs[32]; /* system registers, including psw */
reg_t pc;
int dummy_mem; /* where invalid accesses go */
} v850_regs;
 
struct _sim_cpu
{
/* ... simulator specific members ... */
v850_regs reg;
reg_t psw_mask; /* only allow non-reserved bits to be set */
sim_event *pending_nmi;
/* ... base type ... */
sim_cpu_base base;
};
 
#define CIA_GET(CPU) ((CPU)->reg.pc + 0)
#define CIA_SET(CPU,VAL) ((CPU)->reg.pc = (VAL))
 
struct sim_state {
sim_cpu cpu[MAX_NR_PROCESSORS];
#if (WITH_SMP)
#define STATE_CPU(sd,n) (&(sd)->cpu[n])
#else
#define STATE_CPU(sd,n) (&(sd)->cpu[0])
#endif
#if 0
SIM_ADDR rom_size;
SIM_ADDR low_end;
SIM_ADDR high_start;
SIM_ADDR high_base;
void *mem;
#endif
sim_state_base base;
};
 
/* For compatibility, until all functions converted to passing
SIM_DESC as an argument */
extern SIM_DESC simulator;
 
 
#define V850_ROM_SIZE 0x8000
#define V850_LOW_END 0x200000
#define V850_HIGH_START 0xffe000
 
 
/* Because we are still using the old semantic table, provide compat
macro's that store the instruction where the old simops expects
it. */
 
extern uint32 OP[4];
#if 0
OP[0] = inst & 0x1f; /* RRRRR -> reg1 */
OP[1] = (inst >> 11) & 0x1f; /* rrrrr -> reg2 */
OP[2] = (inst >> 16) & 0xffff; /* wwwww -> reg3 OR imm16 */
OP[3] = inst;
#endif
 
#define SAVE_1 \
PC = cia; \
OP[0] = instruction_0 & 0x1f; \
OP[1] = (instruction_0 >> 11) & 0x1f; \
OP[2] = 0; \
OP[3] = instruction_0
 
#define COMPAT_1(CALL) \
SAVE_1; \
PC += (CALL); \
nia = PC
 
#define SAVE_2 \
PC = cia; \
OP[0] = instruction_0 & 0x1f; \
OP[1] = (instruction_0 >> 11) & 0x1f; \
OP[2] = instruction_1; \
OP[3] = (instruction_1 << 16) | instruction_0
 
#define COMPAT_2(CALL) \
SAVE_2; \
PC += (CALL); \
nia = PC
 
 
/* new */
#define GR ((CPU)->reg.regs)
#define SR ((CPU)->reg.sregs)
 
/* old */
#define State (STATE_CPU (simulator, 0)->reg)
#define PC (State.pc)
#define SP (State.regs[3])
#define EP (State.regs[30])
 
#define EIPC (State.sregs[0])
#define EIPSW (State.sregs[1])
#define FEPC (State.sregs[2])
#define FEPSW (State.sregs[3])
#define ECR (State.sregs[4])
#define PSW (State.sregs[5])
#define CTPC (SR[16])
#define CTPSW (SR[17])
#define DBPC (State.sregs[18])
#define DBPSW (State.sregs[19])
#define CTBP (State.sregs[20])
 
#define PSW_US BIT32 (8)
#define PSW_NP 0x80
#define PSW_EP 0x40
#define PSW_ID 0x20
#define PSW_SAT 0x10
#define PSW_CY 0x8
#define PSW_OV 0x4
#define PSW_S 0x2
#define PSW_Z 0x1
 
#define SEXT3(x) ((((x)&0x7)^(~0x3))+0x4)
 
/* sign-extend a 4-bit number */
#define SEXT4(x) ((((x)&0xf)^(~0x7))+0x8)
 
/* sign-extend a 5-bit number */
#define SEXT5(x) ((((x)&0x1f)^(~0xf))+0x10)
 
/* sign-extend a 9-bit number */
#define SEXT9(x) ((((x)&0x1ff)^(~0xff))+0x100)
 
/* sign-extend a 22-bit number */
#define SEXT22(x) ((((x)&0x3fffff)^(~0x1fffff))+0x200000)
 
/* sign extend a 40 bit number */
#define SEXT40(x) ((((x) & UNSIGNED64 (0xffffffffff)) \
^ (~UNSIGNED64 (0x7fffffffff))) \
+ UNSIGNED64 (0x8000000000))
 
/* sign extend a 44 bit number */
#define SEXT44(x) ((((x) & UNSIGNED64 (0xfffffffffff)) \
^ (~ UNSIGNED64 (0x7ffffffffff))) \
+ UNSIGNED64 (0x80000000000))
 
/* sign extend a 60 bit number */
#define SEXT60(x) ((((x) & UNSIGNED64 (0xfffffffffffffff)) \
^ (~ UNSIGNED64 (0x7ffffffffffffff))) \
+ UNSIGNED64 (0x800000000000000))
 
/* No sign extension */
#define NOP(x) (x)
 
#define INC_ADDR(x,i) x = ((State.MD && x == MOD_E) ? MOD_S : (x)+(i))
 
#define RLW(x) load_mem (x, 4)
 
/* Function declarations. */
 
#define IMEM16(EA) \
sim_core_read_aligned_2 (CPU, PC, exec_map, (EA))
 
#define IMEM16_IMMED(EA,N) \
sim_core_read_aligned_2 (STATE_CPU (sd, 0), \
PC, exec_map, (EA) + (N) * 2)
 
#define load_mem(ADDR,LEN) \
sim_core_read_unaligned_##LEN (STATE_CPU (simulator, 0), \
PC, read_map, (ADDR))
 
#define store_mem(ADDR,LEN,DATA) \
sim_core_write_unaligned_##LEN (STATE_CPU (simulator, 0), \
PC, write_map, (ADDR), (DATA))
 
 
/* compare cccc field against PSW */
int condition_met (unsigned code);
 
 
/* Debug/tracing calls */
 
enum op_types
{
OP_UNKNOWN,
OP_NONE,
OP_TRAP,
OP_REG,
OP_REG_REG,
OP_REG_REG_CMP,
OP_REG_REG_MOVE,
OP_IMM_REG,
OP_IMM_REG_CMP,
OP_IMM_REG_MOVE,
OP_COND_BR,
OP_LOAD16,
OP_STORE16,
OP_LOAD32,
OP_STORE32,
OP_JUMP,
OP_IMM_REG_REG,
OP_UIMM_REG_REG,
OP_IMM16_REG_REG,
OP_UIMM16_REG_REG,
OP_BIT,
OP_EX1,
OP_EX2,
OP_LDSR,
OP_STSR,
OP_BIT_CHANGE,
OP_REG_REG_REG,
OP_REG_REG3,
OP_IMM_REG_REG_REG,
OP_PUSHPOP1,
OP_PUSHPOP2,
OP_PUSHPOP3,
};
 
#ifdef DEBUG
void trace_input PARAMS ((char *name, enum op_types type, int size));
void trace_output PARAMS ((enum op_types result));
void trace_result PARAMS ((int has_result, unsigned32 result));
 
extern int trace_num_values;
extern unsigned32 trace_values[];
extern unsigned32 trace_pc;
extern const char *trace_name;
extern int trace_module;
 
#define TRACE_BRANCH0() \
do { \
if (TRACE_BRANCH_P (CPU)) { \
trace_module = TRACE_BRANCH_IDX; \
trace_pc = cia; \
trace_name = itable[MY_INDEX].name; \
trace_num_values = 0; \
trace_result (1, (nia)); \
} \
} while (0)
 
#define TRACE_BRANCH1(IN1) \
do { \
if (TRACE_BRANCH_P (CPU)) { \
trace_module = TRACE_BRANCH_IDX; \
trace_pc = cia; \
trace_name = itable[MY_INDEX].name; \
trace_values[0] = (IN1); \
trace_num_values = 1; \
trace_result (1, (nia)); \
} \
} while (0)
 
#define TRACE_BRANCH2(IN1, IN2) \
do { \
if (TRACE_BRANCH_P (CPU)) { \
trace_module = TRACE_BRANCH_IDX; \
trace_pc = cia; \
trace_name = itable[MY_INDEX].name; \
trace_values[0] = (IN1); \
trace_values[1] = (IN2); \
trace_num_values = 2; \
trace_result (1, (nia)); \
} \
} while (0)
 
#define TRACE_BRANCH3(IN1, IN2, IN3) \
do { \
if (TRACE_BRANCH_P (CPU)) { \
trace_module = TRACE_BRANCH_IDX; \
trace_pc = cia; \
trace_name = itable[MY_INDEX].name; \
trace_values[0] = (IN1); \
trace_values[1] = (IN2); \
trace_values[2] = (IN3); \
trace_num_values = 3; \
trace_result (1, (nia)); \
} \
} while (0)
 
#define TRACE_LD(ADDR,RESULT) \
do { \
if (TRACE_MEMORY_P (CPU)) { \
trace_module = TRACE_MEMORY_IDX; \
trace_pc = cia; \
trace_name = itable[MY_INDEX].name; \
trace_values[0] = (ADDR); \
trace_num_values = 1; \
trace_result (1, (RESULT)); \
} \
} while (0)
 
#define TRACE_LD_NAME(NAME, ADDR,RESULT) \
do { \
if (TRACE_MEMORY_P (CPU)) { \
trace_module = TRACE_MEMORY_IDX; \
trace_pc = cia; \
trace_name = (NAME); \
trace_values[0] = (ADDR); \
trace_num_values = 1; \
trace_result (1, (RESULT)); \
} \
} while (0)
 
#define TRACE_ST(ADDR,RESULT) \
do { \
if (TRACE_MEMORY_P (CPU)) { \
trace_module = TRACE_MEMORY_IDX; \
trace_pc = cia; \
trace_name = itable[MY_INDEX].name; \
trace_values[0] = (ADDR); \
trace_num_values = 1; \
trace_result (1, (RESULT)); \
} \
} while (0)
 
#else
#define trace_input(NAME, IN1, IN2)
#define trace_output(RESULT)
#define trace_result(HAS_RESULT, RESULT)
 
#define TRACE_ALU_INPUT0()
#define TRACE_ALU_INPUT1(IN0)
#define TRACE_ALU_INPUT2(IN0, IN1)
#define TRACE_ALU_INPUT2(IN0, IN1)
#define TRACE_ALU_INPUT2(IN0, IN1 INS2)
#define TRACE_ALU_RESULT(RESULT)
 
#define TRACE_BRANCH0()
#define TRACE_BRANCH1(IN1)
#define TRACE_BRANCH2(IN1, IN2)
#define TRACE_BRANCH2(IN1, IN2, IN3)
 
#define TRACE_LD(ADDR,RESULT)
#define TRACE_ST(ADDR,RESULT)
 
#endif
 
#define GPR_SET(N, VAL) (State.regs[(N)] = (VAL))
#define GPR_CLEAR(N) (State.regs[(N)] = 0)
 
extern void divun ( unsigned int N,
unsigned long int als,
unsigned long int sfi,
unsigned32 /*unsigned long int*/ * quotient_ptr,
unsigned32 /*unsigned long int*/ * remainder_ptr,
int *overflow_ptr
);
extern void divn ( unsigned int N,
unsigned long int als,
unsigned long int sfi,
signed32 /*signed long int*/ * quotient_ptr,
signed32 /*signed long int*/ * remainder_ptr,
int *overflow_ptr
);
extern int type1_regs[];
extern int type2_regs[];
extern int type3_regs[];
 
#endif
sim-main.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: simops.h =================================================================== --- simops.h (nonexistent) +++ simops.h (revision 33) @@ -0,0 +1,78 @@ +#ifndef SIMOPS_H +#define SIMOPS_H +int OP_380 (void); +int OP_480 (void); +int OP_501 (void); +int OP_700 (void); +int OP_720 (void); +int OP_10720 (void); +int OP_740 (void); +int OP_760 (void); +int OP_10760 (void); +int OP_1C0 (void); +int OP_240 (void); +int OP_600 (void); +int OP_1A0 (void); +int OP_180 (void); +int OP_E0 (void); +int OP_2E0 (void); +int OP_6E0 (void); +int OP_1E0 (void); +int OP_260 (void); +int OP_7E0 (void); +int OP_C0 (void); +int OP_220 (void); +int OP_A0 (void); +int OP_660 (void); +int OP_80 (void); +int OP_160 (void); +int OP_200 (void); +int OP_640 (void); +int OP_2A0 (void); +int OP_A007E0 (void); +int OP_2C0 (void); +int OP_C007E0 (void); +int OP_280 (void); +int OP_8007E0 (void); +int OP_100 (void); +int OP_680 (void); +int OP_140 (void); +int OP_6C0 (void); +int OP_120 (void); +int OP_6A0 (void); +int OP_20 (void); +int OP_7C0 (void); +int OP_47C0 (void); +int OP_87C0 (void); +int OP_C7C0 (void); +int OP_16007E0 (void); +int OP_16087E0 (void); +int OP_12007E0 (void); +int OP_10007E0 (void); +int OP_E607E0 (void); +int OP_22207E0 (void); +int OP_E407E0 (void); +int OP_E207E0 (void); +int OP_E007E0 (void); +int OP_20007E0 (void); +int OP_1C207E0 (void); +int OP_1C007E0 (void); +int OP_18207E0 (void); +int OP_18007E0 (void); +int OP_2C207E0 (void); +int OP_2C007E0 (void); +int OP_28207E0 (void); +int OP_28007E0 (void); +int OP_24207E0 (void); +int OP_24007E0 (void); +int OP_107E0 (void); +int OP_10780 (void); +int OP_1B0780 (void); +int OP_130780 (void); +int OP_B0780 (void); +int OP_30780 (void); +int OP_22007E0 (void); +int OP_307F0 (void); +int OP_107F0 (void); +int OP_307E0 (void); +#endif
simops.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: v850_sim.h =================================================================== --- v850_sim.h (nonexistent) +++ v850_sim.h (revision 33) @@ -0,0 +1,8 @@ +struct simops +{ + unsigned long opcode; + unsigned long mask; + int (* func) PARAMS ((void)); + int numops; + int operands[12]; +};
v850_sim.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: interp.c =================================================================== --- interp.c (nonexistent) +++ interp.c (revision 33) @@ -0,0 +1,350 @@ +#include "sim-main.h" +#include "sim-options.h" +#include "v850_sim.h" +#include "sim-assert.h" +#include "itable.h" + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#include "bfd.h" + +#ifndef INLINE +#ifdef __GNUC__ +#define INLINE inline +#else +#define INLINE +#endif +#endif + +static const char * get_insn_name (sim_cpu *, int); + +/* For compatibility */ +SIM_DESC simulator; + + + +/* v850 interrupt model */ + +enum interrupt_type +{ + int_reset, + int_nmi, + int_intov1, + int_intp10, + int_intp11, + int_intp12, + int_intp13, + int_intcm4, + num_int_types +}; + +char *interrupt_names[] = { + "reset", + "nmi", + "intov1", + "intp10", + "intp11", + "intp12", + "intp13", + "intcm4", + NULL +}; + +static void +do_interrupt (sd, data) + SIM_DESC sd; + void *data; +{ + char **interrupt_name = (char**)data; + enum interrupt_type inttype; + inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names); + + /* For a hardware reset, drop everything and jump to the start + address */ + if (inttype == int_reset) + { + PC = 0; + PSW = 0x20; + ECR = 0; + sim_engine_restart (sd, NULL, NULL, NULL_CIA); + } + + /* Deliver an NMI when allowed */ + if (inttype == int_nmi) + { + if (PSW & PSW_NP) + { + /* We're already working on an NMI, so this one must wait + around until the previous one is done. The processor + ignores subsequent NMIs, so we don't need to count them. + Just keep re-scheduling a single NMI until it manages to + be delivered */ + if (STATE_CPU (sd, 0)->pending_nmi != NULL) + sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi); + STATE_CPU (sd, 0)->pending_nmi = + sim_events_schedule (sd, 1, do_interrupt, data); + return; + } + else + { + /* NMI can be delivered. Do not deschedule pending_nmi as + that, if still in the event queue, is a second NMI that + needs to be delivered later. */ + FEPC = PC; + FEPSW = PSW; + /* Set the FECC part of the ECR. */ + ECR &= 0x0000ffff; + ECR |= 0x10; + PSW |= PSW_NP; + PSW &= ~PSW_EP; + PSW |= PSW_ID; + PC = 0x10; + sim_engine_restart (sd, NULL, NULL, NULL_CIA); + } + } + + /* deliver maskable interrupt when allowed */ + if (inttype > int_nmi && inttype < num_int_types) + { + if ((PSW & PSW_NP) || (PSW & PSW_ID)) + { + /* Can't deliver this interrupt, reschedule it for later */ + sim_events_schedule (sd, 1, do_interrupt, data); + return; + } + else + { + /* save context */ + EIPC = PC; + EIPSW = PSW; + /* Disable further interrupts. */ + PSW |= PSW_ID; + /* Indicate that we're doing interrupt not exception processing. */ + PSW &= ~PSW_EP; + /* Clear the EICC part of the ECR, will set below. */ + ECR &= 0xffff0000; + switch (inttype) + { + case int_intov1: + PC = 0x80; + ECR |= 0x80; + break; + case int_intp10: + PC = 0x90; + ECR |= 0x90; + break; + case int_intp11: + PC = 0xa0; + ECR |= 0xa0; + break; + case int_intp12: + PC = 0xb0; + ECR |= 0xb0; + break; + case int_intp13: + PC = 0xc0; + ECR |= 0xc0; + break; + case int_intcm4: + PC = 0xd0; + ECR |= 0xd0; + break; + default: + /* Should never be possible. */ + sim_engine_abort (sd, NULL, NULL_CIA, + "do_interrupt - internal error - bad switch"); + break; + } + } + sim_engine_restart (sd, NULL, NULL, NULL_CIA); + } + + /* some other interrupt? */ + sim_engine_abort (sd, NULL, NULL_CIA, + "do_interrupt - internal error - interrupt %d unknown", + inttype); +} + +/* Return name of an insn, used by insn profiling. */ + +static const char * +get_insn_name (sim_cpu *cpu, int i) +{ + return itable[i].name; +} + +/* These default values correspond to expected usage for the chip. */ + +uint32 OP[4]; + + +SIM_DESC +sim_open (kind, cb, abfd, argv) + SIM_OPEN_KIND kind; + host_callback *cb; + struct bfd *abfd; + char **argv; +{ + SIM_DESC sd = sim_state_alloc (kind, cb); + int mach; + + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + /* for compatibility */ + simulator = sd; + + /* FIXME: should be better way of setting up interrupts */ + STATE_WATCHPOINTS (sd)->pc = &(PC); + STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); + STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt; + STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names; + + /* Initialize the mechanism for doing insn profiling. */ + CPU_INSN_NAME (STATE_CPU (sd, 0)) = get_insn_name; + CPU_MAX_INSNS (STATE_CPU (sd, 0)) = nr_itable_entries; + + if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) + return 0; + + /* Allocate core managed memory */ + + /* "Mirror" the ROM addresses below 1MB. */ + sim_do_commandf (sd, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE); + /* Chunk of ram adjacent to rom */ + sim_do_commandf (sd, "memory region 0x100000,0x%lx", V850_LOW_END-0x100000); + /* peripheral I/O region - mirror 1K across 4k (0x1000) */ + sim_do_command (sd, "memory region 0xfff000,0x1000,1024"); + /* similarly if in the internal RAM region */ + sim_do_command (sd, "memory region 0xffe000,0x1000,1024"); + + /* getopt will print the error message so we just have to exit if this fails. + FIXME: Hmmm... in the case of gdb we need getopt to call + print_filtered. */ + if (sim_parse_args (sd, argv) != SIM_RC_OK) + { + /* Uninstall the modules to avoid memory leaks, + file descriptor leaks, etc. */ + sim_module_uninstall (sd); + return 0; + } + + /* check for/establish the a reference program image */ + if (sim_analyze_program (sd, + (STATE_PROG_ARGV (sd) != NULL + ? *STATE_PROG_ARGV (sd) + : NULL), + abfd) != SIM_RC_OK) + { + sim_module_uninstall (sd); + return 0; + } + + /* establish any remaining configuration options */ + if (sim_config (sd) != SIM_RC_OK) + { + sim_module_uninstall (sd); + return 0; + } + + if (sim_post_argv_init (sd) != SIM_RC_OK) + { + /* Uninstall the modules to avoid memory leaks, + file descriptor leaks, etc. */ + sim_module_uninstall (sd); + return 0; + } + + + /* determine the machine type */ + if (STATE_ARCHITECTURE (sd) != NULL + && STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850) + mach = STATE_ARCHITECTURE (sd)->mach; + else + mach = bfd_mach_v850; /* default */ + + /* set machine specific configuration */ + switch (mach) + { + case bfd_mach_v850: + case bfd_mach_v850e: + case bfd_mach_v850e1: + STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT + | PSW_CY | PSW_OV | PSW_S | PSW_Z); + break; + } + + return sd; +} + + +void +sim_close (sd, quitting) + SIM_DESC sd; + int quitting; +{ + sim_module_uninstall (sd); +} + +SIM_RC +sim_create_inferior (sd, prog_bfd, argv, env) + SIM_DESC sd; + struct bfd *prog_bfd; + char **argv; + char **env; +{ + memset (&State, 0, sizeof (State)); + if (prog_bfd != NULL) + PC = bfd_get_start_address (prog_bfd); + return SIM_RC_OK; +} + +int +sim_fetch_register (sd, rn, memory, length) + SIM_DESC sd; + int rn; + unsigned char *memory; + int length; +{ + *(unsigned32*)memory = H2T_4 (State.regs[rn]); + return -1; +} + +int +sim_store_register (sd, rn, memory, length) + SIM_DESC sd; + int rn; + unsigned char *memory; + int length; +{ + State.regs[rn] = T2H_4 (*(unsigned32*)memory); + return -1; +} + +void +sim_do_command (sd, cmd) + SIM_DESC sd; + char *cmd; +{ + char *mm_cmd = "memory-map"; + char *int_cmd = "interrupt"; + + if (sim_args_command (sd, cmd) != SIM_RC_OK) + { + if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0)) + sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n"); + else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0) + sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n"); + else + sim_io_eprintf (sd, "Unknown command `%s'\n", cmd); + } +}
interp.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: configure.ac =================================================================== --- configure.ac (nonexistent) +++ configure.ac (revision 33) @@ -0,0 +1,22 @@ +dnl Process this file with autoconf to produce a configure script. +AC_PREREQ(2.59)dnl +AC_INIT(Makefile.in) +AC_CONFIG_HEADER(config.h:config.in) + +sinclude(../common/aclocal.m4) + +# Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around +# it by inlining the macro's contents. +sinclude(../common/common.m4) + +SIM_AC_OPTION_ENDIAN(LITTLE_ENDIAN) +SIM_AC_OPTION_ALIGNMENT(,NONSTRICT_ALIGNMENT) +SIM_AC_OPTION_HOSTENDIAN +SIM_AC_OPTION_WARNINGS +SIM_AC_OPTION_RESERVED_BITS +SIM_AC_OPTION_BITSIZE(32,31) + +AC_CHECK_FUNCS(time chmod utime fork execve execv chown) +AC_CHECK_HEADERS(unistd.h stdlib.h string.h strings.h utime.h time.h) + +SIM_AC_OUTPUT
configure.ac Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: v850.igen =================================================================== --- v850.igen (nonexistent) +++ v850.igen (revision 33) @@ -0,0 +1,1205 @@ +:option:::insn-bit-size:16 +:option:::hi-bit-nr:15 + + +:option:::format-names:I,II,III,IV,V,VI,VII,VIII,IX,X +:option:::format-names:XI,XII,XIII +:option:::format-names:XIV,XV +:option:::format-names:Z + + +:model:::v850:v850: + +:option:::multi-sim:true +:model:::v850e:v850e: +:option:::multi-sim:true +:model:::v850e1:v850e1: + +// Cache macros + +:cache:::unsigned:reg1:RRRRR:(RRRRR) +:cache:::unsigned:reg2:rrrrr:(rrrrr) +:cache:::unsigned:reg3:wwwww:(wwwww) + +:cache:::unsigned:disp4:dddd:(dddd) +:cache:::unsigned:disp5:dddd:(dddd << 1) +:cache:::unsigned:disp7:ddddddd:ddddddd +:cache:::unsigned:disp8:ddddddd:(ddddddd << 1) +:cache:::unsigned:disp8:dddddd:(dddddd << 2) +:cache:::unsigned:disp9:ddddd,ddd:SEXT32 ((ddddd << 4) + (ddd << 1), 9 - 1) +:cache:::unsigned:disp16:dddddddddddddddd:EXTEND16 (dddddddddddddddd) +:cache:::unsigned:disp16:ddddddddddddddd: EXTEND16 (ddddddddddddddd << 1) +:cache:::unsigned:disp22:dddddd,ddddddddddddddd: SEXT32 ((dddddd << 16) + (ddddddddddddddd << 1), 22 - 1) + +:cache:::unsigned:imm5:iiiii:SEXT32 (iiiii, 4) +:cache:::unsigned:imm6:iiiiii:iiiiii +:cache:::unsigned:imm9:iiiii,IIII:SEXT ((IIII << 5) + iiiii, 9 - 1) +:cache:::unsigned:imm5:iiii:(32 - (iiii << 1)) +:cache:::unsigned:simm16:iiiiiiiiiiiiiiii:EXTEND16 (iiiiiiiiiiiiiiii) +:cache:::unsigned:uimm16:iiiiiiiiiiiiiiii:iiiiiiiiiiiiiiii +:cache:::unsigned:imm32:iiiiiiiiiiiiiiii,IIIIIIIIIIIIIIII:(iiiiiiiiiiiiiiii < 16 + IIIIIIIIIIIIIIII) +:cache:::unsigned:uimm32:iiiiiiiiiiiiiiii,dddddddddddddddd:((iiiiiiiiiiiiiiii << 16) + dddddddddddddddd) + +:cache:::unsigned:vector:iiiii:iiiii + +:cache:::unsigned:list12:L,LLLLLLLLLLL:((L << 11) + LLLLLLLLLLL) +:cache:::unsigned:list18:LLLL,LLLLLLLLLLLL:((LLLL << 12) + LLLLLLLLLLLL) + +:cache:::unsigned:bit3:bbb:bbb + + +// What do we do with an illegal instruction? +:internal::::illegal: +{ + sim_io_eprintf (SD, "Illegal instruction at address 0x%lx\n", + (unsigned long) cia); + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); +} + + + +// Add + +rrrrr,001110,RRRRR:I:::add +"add r, r" +{ + COMPAT_1 (OP_1C0 ()); +} + +rrrrr,010010,iiiii:II:::add +"add ,r" +{ + COMPAT_1 (OP_240 ()); +} + + + +// ADDI +rrrrr,110000,RRRRR + iiiiiiiiiiiiiiii:VI:::addi +"addi , r, r" +{ + COMPAT_2 (OP_600 ()); +} + + + +// AND +rrrrr,001010,RRRRR:I:::and +"and r, r" +{ + COMPAT_1 (OP_140 ()); +} + + + +// ANDI +rrrrr,110110,RRRRR + iiiiiiiiiiiiiiii:VI:::andi +"andi , r, r" +{ + COMPAT_2 (OP_6C0 ()); +} + + + +// Map condition code to a string +:%s::::cccc:int cccc +{ + switch (cccc) + { + case 0xf: return "gt"; + case 0xe: return "ge"; + case 0x6: return "lt"; + + case 0x7: return "le"; + + case 0xb: return "h"; + case 0x9: return "nl"; + case 0x1: return "l"; + + case 0x3: return "nh"; + + case 0x2: return "e"; + + case 0xa: return "ne"; + + case 0x0: return "v"; + case 0x8: return "nv"; + case 0x4: return "n"; + case 0xc: return "p"; + /* case 0x1: return "c"; */ + /* case 0x9: return "nc"; */ + /* case 0x2: return "z"; */ + /* case 0xa: return "nz"; */ + case 0x5: return "r"; /* always */ + case 0xd: return "sa"; + } + return "(null)"; +} + + +// Bcond +ddddd,1011,ddd,cccc:III:::Bcond +"b%s " +{ + int cond; + if ((ddddd == 0x00) && (ddd == 0x00) && (cccc == 0x05)) { + // Special case - treat "br *" like illegal instruction + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); + } else { + cond = condition_met (cccc); + if (cond) + nia = cia + disp9; + TRACE_BRANCH1 (cond); + } +} + + + +// BSH +rrrrr,11111100000 + wwwww,01101000010:XII:::bsh +*v850e +*v850e1 +"bsh r, r" +{ + unsigned32 value; + TRACE_ALU_INPUT1 (GR[reg2]); + + value = (MOVED32 (GR[reg2], 23, 16, 31, 24) + | MOVED32 (GR[reg2], 31, 24, 23, 16) + | MOVED32 (GR[reg2], 7, 0, 15, 8) + | MOVED32 (GR[reg2], 15, 8, 7, 0)); + + GR[reg3] = value; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + if ((value & 0xffff) == 0) PSW |= PSW_Z; + if (value & 0x80000000) PSW |= PSW_S; + if (((value & 0xff) == 0) || ((value & 0xff00) == 0)) PSW |= PSW_CY; + + TRACE_ALU_RESULT (GR[reg3]); +} + +// BSW +rrrrr,11111100000 + wwwww,01101000000:XII:::bsw +*v850e +*v850e1 +"bsw r, r" +{ +#define WORDHASNULLBYTE(x) (((x) - 0x01010101) & ~(x)&0x80808080) + unsigned32 value; + TRACE_ALU_INPUT1 (GR[reg2]); + + value = GR[reg2]; + value >>= 24; + value |= (GR[reg2] << 24); + value |= ((GR[reg2] << 8) & 0x00ff0000); + value |= ((GR[reg2] >> 8) & 0x0000ff00); + GR[reg3] = value; + + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + + if (value == 0) PSW |= PSW_Z; + if (value & 0x80000000) PSW |= PSW_S; + if (WORDHASNULLBYTE (value)) PSW |= PSW_CY; + + TRACE_ALU_RESULT (GR[reg3]); +} + +// CALLT +0000001000,iiiiii:II:::callt +*v850e +*v850e1 +"callt " +{ + unsigned32 adr; + unsigned32 off; + CTPC = cia + 2; + CTPSW = PSW; + adr = (CTBP & ~1) + (imm6 << 1); + off = load_mem (adr, 2) & ~1; /* Force alignment */ + nia = (CTBP & ~1) + off; + TRACE_BRANCH3 (adr, CTBP, off); +} + + +// CLR1 +10,bbb,111110,RRRRR + dddddddddddddddd:VIII:::clr1 +"clr1 , [r]" +{ + COMPAT_2 (OP_87C0 ()); +} + +rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1 +*v850e +*v850e1 +"clr1 r, [r]" +{ + COMPAT_2 (OP_E407E0 ()); +} + + +// CTRET +0000011111100000 + 0000000101000100:X:::ctret +*v850e +*v850e1 +"ctret" +{ + nia = (CTPC & ~1); + PSW = (CTPSW & (CPU)->psw_mask); + TRACE_BRANCH1 (PSW); +} + +// CMOV +rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov +*v850e +*v850e1 +"cmov %s, r, r, r" +{ + int cond = condition_met (cccc); + TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]); + GR[reg3] = cond ? GR[reg1] : GR[reg2]; + TRACE_ALU_RESULT (GR[reg3]); +} + +rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov +*v850e +*v850e1 +"cmov %s, , r, r" +{ + int cond = condition_met (cccc); + TRACE_ALU_INPUT3 (cond, imm5, GR[reg2]); + GR[reg3] = cond ? imm5 : GR[reg2]; + TRACE_ALU_RESULT (GR[reg3]); +} + +// CMP +rrrrr,001111,RRRRR:I:::cmp +"cmp r, r" +{ + COMPAT_1 (OP_1E0 ()); +} + +rrrrr,010011,iiiii:II:::cmp +"cmp , r" +{ + COMPAT_1 (OP_260 ()); +} + + + +// DI +0000011111100000 + 0000000101100000:X:::di +"di" +{ + COMPAT_2 (OP_16007E0 ()); +} + + + +// DISPOSE +// 0000011001,iiiii,L + LLLLLLLLLLL,00000:XIII:::dispose +// "dispose , " +0000011001,iiiii,L + LLLLLLLLLLL,RRRRR:XIII:::dispose +*v850e +*v850e1 +"dispose , ":RRRRR == 0 +"dispose , , [reg1]" +{ + int i; + SAVE_2; + + trace_input ("dispose", OP_PUSHPOP1, 0); + + SP += (OP[3] & 0x3e) << 1; + + /* Load the registers with lower number registers being retrieved + from higher addresses. */ + for (i = 12; i--;) + if ((OP[3] & (1 << type1_regs[ i ]))) + { + State.regs[ 20 + i ] = load_mem (SP, 4); + SP += 4; + } + + if ((OP[3] & 0x1f0000) != 0) + { + nia = State.regs[ (OP[3] >> 16) & 0x1f]; + } + + trace_output (OP_PUSHPOP1); +} + + +// DIV +rrrrr,111111,RRRRR + wwwww,01011000000:XI:::div +*v850e +*v850e1 +"div r, r, r" +{ + COMPAT_2 (OP_2C007E0 ()); +} + + +// DIVH +rrrrr!0,000010,RRRRR!0:I:::divh +"divh r, r" +{ + unsigned32 ov, s, z; + signed long int op0, op1, result; + + trace_input ("divh", OP_REG_REG, 0); + + PC = cia; + OP[0] = instruction_0 & 0x1f; + OP[1] = (instruction_0 >> 11) & 0x1f; + + /* Compute the result. */ + op0 = EXTEND16 (State.regs[OP[0]]); + op1 = State.regs[OP[1]]; + + if (op0 == -1 && op1 == 0x80000000) + { + PSW &= ~PSW_Z; + PSW |= PSW_OV | PSW_S; + State.regs[OP[1]] = 0x80000000; + } + else if (op0 == 0) + { + PSW |= PSW_OV; + } + else + { + result = (signed32) op1 / op0; + ov = 0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (ov ? PSW_OV : 0)); + } + + trace_output (OP_REG_REG); + + PC += 2; + nia = PC; +} + +rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh +*v850e +*v850e1 +"divh r, r, r" +{ + COMPAT_2 (OP_28007E0 ()); +} + + +// DIVHU +rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu +*v850e +*v850e1 +"divhu r, r, r" +{ + COMPAT_2 (OP_28207E0 ()); +} + + +// DIVU +rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu +*v850e +*v850e1 +"divu r, r, r" +{ + COMPAT_2 (OP_2C207E0 ()); +} + + +// EI +1000011111100000 + 0000000101100000:X:::ei +"ei" +{ + COMPAT_2 (OP_16087E0 ()); +} + + + +// HALT +0000011111100000 + 0000000100100000:X:::halt +"halt" +{ + COMPAT_2 (OP_12007E0 ()); +} + + + +// HSW +rrrrr,11111100000 + wwwww,01101000100:XII:::hsw +*v850e +*v850e1 +"hsw r, r" +{ + unsigned32 value; + TRACE_ALU_INPUT1 (GR[reg2]); + + value = GR[reg2]; + value >>= 16; + value |= (GR[reg2] << 16); + + GR[reg3] = value; + + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + + if (value == 0) PSW |= PSW_Z; + if (value & 0x80000000) PSW |= PSW_S; + if (((value & 0xffff) == 0) || (value & 0xffff0000) == 0) PSW |= PSW_CY; + + TRACE_ALU_RESULT (GR[reg3]); +} + + + +// JARL +rrrrr!0,11110,dddddd + ddddddddddddddd,0:V:::jarl +"jarl , r" +{ + GR[reg2] = nia; + nia = cia + disp22; + TRACE_BRANCH1 (GR[reg2]); +} + + + +// JMP +00000000011,RRRRR:I:::jmp +"jmp [r]" +{ + nia = GR[reg1] & ~1; + TRACE_BRANCH0 (); +} + + + +// JR +0000011110,dddddd + ddddddddddddddd,0:V:::jr +"jr " +{ + nia = cia + disp22; + TRACE_BRANCH0 (); +} + + + +// LD +rrrrr,111000,RRRRR + dddddddddddddddd:VII:::ld.b +"ld.b [r], r" +{ + COMPAT_2 (OP_700 ()); +} + +rrrrr,111001,RRRRR + ddddddddddddddd,0:VII:::ld.h +"ld.h [r], r" +{ + COMPAT_2 (OP_720 ()); +} + +rrrrr,111001,RRRRR + ddddddddddddddd,1:VII:::ld.w +"ld.w [r], r" +{ + COMPAT_2 (OP_10720 ()); +} + +rrrrr!0,11110,b,RRRRR + ddddddddddddddd,1:VII:::ld.bu +*v850e +*v850e1 +"ld.bu [r], r" +{ + COMPAT_2 (OP_10780 ()); +} + +rrrrr!0,111111,RRRRR + ddddddddddddddd,1:VII:::ld.hu +*v850e +*v850e1 +"ld.hu [r], r" +{ + COMPAT_2 (OP_107E0 ()); +} + + +// LDSR +regID,111111,RRRRR + 0000000000100000:IX:::ldsr +"ldsr r, s" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + + if (&PSW == &SR[regID]) + PSW = (GR[reg1] & (CPU)->psw_mask); + else + SR[regID] = GR[reg1]; + + TRACE_ALU_RESULT (SR[regID]); +} + + + +// MOV +rrrrr!0,000000,RRRRR:I:::mov +"mov r, r" +{ + TRACE_ALU_INPUT0 (); + GR[reg2] = GR[reg1]; + TRACE_ALU_RESULT (GR[reg2]); +} + + +rrrrr!0,010000,iiiii:II:::mov +"mov , r" +{ + COMPAT_1 (OP_200 ()); +} + +00000110001,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::mov +*v850e +*v850e1 +"mov , r" +{ + SAVE_2; + trace_input ("mov", OP_IMM_REG, 4); + State.regs[ OP[0] ] = load_mem (PC + 2, 4); + trace_output (OP_IMM_REG); +} + + + +// MOVEA +rrrrr!0,110001,RRRRR + iiiiiiiiiiiiiiii:VI:::movea +"movea , r, r" +{ + TRACE_ALU_INPUT2 (GR[reg1], simm16); + GR[reg2] = GR[reg1] + simm16; + TRACE_ALU_RESULT (GR[reg2]); +} + + + +// MOVHI +rrrrr!0,110010,RRRRR + iiiiiiiiiiiiiiii:VI:::movhi +"movhi , r, r" +{ + COMPAT_2 (OP_640 ()); +} + + + +// MUL +rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul +*v850e +*v850e1 +"mul r, r, r" +{ + COMPAT_2 (OP_22007E0 ()); +} + +rrrrr,111111,iiiii + wwwww,01001,IIII,00:XII:::mul +*v850e +*v850e1 +"mul , r, r" +{ + COMPAT_2 (OP_24007E0 ()); +} + + +// MULH +rrrrr!0,000111,RRRRR:I:::mulh +"mulh r, r" +{ + COMPAT_1 (OP_E0 ()); +} + +rrrrr!0,010111,iiiii:II:::mulh +"mulh , r" +{ + COMPAT_1 (OP_2E0 ()); +} + + + +// MULHI +rrrrr!0,110111,RRRRR + iiiiiiiiiiiiiiii:VI:::mulhi +"mulhi , r, r" +{ + COMPAT_2 (OP_6E0 ()); +} + + + +// MULU +rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu +*v850e +*v850e1 +"mulu r, r, r" +{ + COMPAT_2 (OP_22207E0 ()); +} + +rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu +*v850e +*v850e1 +"mulu , r, r" +{ + COMPAT_2 (OP_24207E0 ()); +} + + + +// NOP +0000000000000000:I:::nop +"nop" +{ + /* do nothing, trace nothing */ +} + + + +// NOT +rrrrr,000001,RRRRR:I:::not +"not r, r" +{ + COMPAT_1 (OP_20 ()); +} + + + +// NOT1 +01,bbb,111110,RRRRR + dddddddddddddddd:VIII:::not1 +"not1 , [r]" +{ + COMPAT_2 (OP_47C0 ()); +} + +rrrrr,111111,RRRRR + 0000000011100010:IX:::not1 +*v850e +*v850e1 +"not1 r, r" +{ + COMPAT_2 (OP_E207E0 ()); +} + + + +// OR +rrrrr,001000,RRRRR:I:::or +"or r, r" +{ + COMPAT_1 (OP_100 ()); +} + + + +// ORI +rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori +"ori , r, r" +{ + COMPAT_2 (OP_680 ()); +} + + + +// PREPARE +0000011110,iiiii,L + LLLLLLLLLLL,00001:XIII:::prepare +*v850e +*v850e1 +"prepare , " +{ + int i; + SAVE_2; + + trace_input ("prepare", OP_PUSHPOP1, 0); + + /* Store the registers with lower number registers being placed at + higher addresses. */ + for (i = 0; i < 12; i++) + if ((OP[3] & (1 << type1_regs[ i ]))) + { + SP -= 4; + store_mem (SP, 4, State.regs[ 20 + i ]); + } + + SP -= (OP[3] & 0x3e) << 1; + + trace_output (OP_PUSHPOP1); +} + + +0000011110,iiiii,L + LLLLLLLLLLL,00011:XIII:::prepare00 +*v850e +*v850e1 +"prepare , , sp" +{ + COMPAT_2 (OP_30780 ()); +} + +0000011110,iiiii,L + LLLLLLLLLLL,01011 + iiiiiiiiiiiiiiii:XIII:::prepare01 +*v850e +*v850e1 +"prepare , , " +{ + COMPAT_2 (OP_B0780 ()); +} + +0000011110,iiiii,L + LLLLLLLLLLL,10011 + iiiiiiiiiiiiiiii:XIII:::prepare10 +*v850e +*v850e1 +"prepare , , " +{ + COMPAT_2 (OP_130780 ()); +} + +0000011110,iiiii,L + LLLLLLLLLLL,11011 + iiiiiiiiiiiiiiii + dddddddddddddddd:XIII:::prepare11 +*v850e +*v850e1 +"prepare , , " +{ + COMPAT_2 (OP_1B0780 ()); +} + + + +// RETI +0000011111100000 + 0000000101000000:X:::reti +"reti" +{ + if ((PSW & PSW_EP)) + { + nia = (EIPC & ~1); + PSW = EIPSW; + } + else if ((PSW & PSW_NP)) + { + nia = (FEPC & ~1); + PSW = FEPSW; + } + else + { + nia = (EIPC & ~1); + PSW = EIPSW; + } + TRACE_BRANCH1 (PSW); +} + + + +// SAR +rrrrr,111111,RRRRR + 0000000010100000:IX:::sar +"sar r, r" +{ + COMPAT_2 (OP_A007E0 ()); +} + +rrrrr,010101,iiiii:II:::sar +"sar , r" +{ + COMPAT_1 (OP_2A0 ()); +} + + + +// SASF +rrrrr,1111110,cccc + 0000001000000000:IX:::sasf +*v850e +*v850e1 +"sasf %s, r" +{ + COMPAT_2 (OP_20007E0 ()); +} + + + + +// SATADD +rrrrr!0,000110,RRRRR:I:::satadd +"satadd r, r" +{ + COMPAT_1 (OP_C0 ()); +} + +rrrrr!0,010001,iiiii:II:::satadd +"satadd , r" +{ + COMPAT_1 (OP_220 ()); +} + + + +// SATSUB +rrrrr!0,000101,RRRRR:I:::satsub +"satsub r, r" +{ + COMPAT_1 (OP_A0 ()); +} + + + +// SATSUBI +rrrrr!0,110011,RRRRR + iiiiiiiiiiiiiiii:VI:::satsubi +"satsubi , r, r" +{ + COMPAT_2 (OP_660 ()); +} + + + +// SATSUBR +rrrrr!0,000100,RRRRR:I:::satsubr +"satsubr r, r" +{ + COMPAT_1 (OP_80 ()); +} + + + +// SETF +rrrrr,1111110,cccc + 0000000000000000:IX:::setf +"setf %s, r" +{ + COMPAT_2 (OP_7E0 ()); +} + + + +// SET1 +00,bbb,111110,RRRRR + dddddddddddddddd:VIII:::set1 +"set1 , [r]" +{ + COMPAT_2 (OP_7C0 ()); +} + +rrrrr,111111,RRRRR + 0000000011100000:IX:::set1 +*v850e +*v850e1 +"set1 r, [r]" +{ + COMPAT_2 (OP_E007E0 ()); +} + + + +// SHL +rrrrr,111111,RRRRR + 0000000011000000:IX:::shl +"shl r, r" +{ + COMPAT_2 (OP_C007E0 ()); +} + +rrrrr,010110,iiiii:II:::shl +"shl , r" +{ + COMPAT_1 (OP_2C0 ()); +} + + + +// SHR +rrrrr,111111,RRRRR + 0000000010000000:IX:::shr +"shr r, r" +{ + COMPAT_2 (OP_8007E0 ()); +} + +rrrrr,010100,iiiii:II:::shr +"shr , r" +{ + COMPAT_1 (OP_280 ()); +} + + + +// SLD +rrrrr,0110,ddddddd:IV:::sld.b +"sld.bu [ep], r":(PSW & PSW_US) +"sld.b [ep], r" +{ + unsigned32 addr = EP + disp7; + unsigned32 result = load_mem (addr, 1); + if (PSW & PSW_US) + { + GR[reg2] = result; + TRACE_LD_NAME ("sld.bu", addr, result); + } + else + { + result = EXTEND8 (result); + GR[reg2] = result; + TRACE_LD (addr, result); + } +} + +rrrrr,1000,ddddddd:IV:::sld.h +"sld.hu [ep], r":(PSW & PSW_US) +"sld.h [ep], r" +{ + unsigned32 addr = EP + disp8; + unsigned32 result = load_mem (addr, 2); + if (PSW & PSW_US) + { + GR[reg2] = result; + TRACE_LD_NAME ("sld.hu", addr, result); + } + else + { + result = EXTEND16 (result); + GR[reg2] = result; + TRACE_LD (addr, result); + } +} + +rrrrr,1010,dddddd,0:IV:::sld.w +"sld.w [ep], r" +{ + unsigned32 addr = EP + disp8; + unsigned32 result = load_mem (addr, 4); + GR[reg2] = result; + TRACE_LD (addr, result); +} + +rrrrr!0,0000110,dddd:IV:::sld.bu +*v850e +*v850e1 +"sld.b [ep], r":(PSW & PSW_US) +"sld.bu [ep], r" +{ + unsigned32 addr = EP + disp4; + unsigned32 result = load_mem (addr, 1); + if (PSW & PSW_US) + { + result = EXTEND8 (result); + GR[reg2] = result; + TRACE_LD_NAME ("sld.b", addr, result); + } + else + { + GR[reg2] = result; + TRACE_LD (addr, result); + } +} + +rrrrr!0,0000111,dddd:IV:::sld.hu +*v850e +*v850e1 +"sld.h [ep], r":(PSW & PSW_US) +"sld.hu [ep], r" +{ + unsigned32 addr = EP + disp5; + unsigned32 result = load_mem (addr, 2); + if (PSW & PSW_US) + { + result = EXTEND16 (result); + GR[reg2] = result; + TRACE_LD_NAME ("sld.h", addr, result); + } + else + { + GR[reg2] = result; + TRACE_LD (addr, result); + } +} + +// SST +rrrrr,0111,ddddddd:IV:::sst.b +"sst.b r, [ep]" +{ + COMPAT_1 (OP_380 ()); +} + +rrrrr,1001,ddddddd:IV:::sst.h +"sst.h r, [ep]" +{ + COMPAT_1 (OP_480 ()); +} + +rrrrr,1010,dddddd,1:IV:::sst.w +"sst.w r, [ep]" +{ + COMPAT_1 (OP_501 ()); +} + +// ST +rrrrr,111010,RRRRR + dddddddddddddddd:VII:::st.b +"st.b r, [r]" +{ + COMPAT_2 (OP_740 ()); +} + +rrrrr,111011,RRRRR + ddddddddddddddd,0:VII:::st.h +"st.h r, [r]" +{ + COMPAT_2 (OP_760 ()); +} + +rrrrr,111011,RRRRR + ddddddddddddddd,1:VII:::st.w +"st.w r, [r]" +{ + COMPAT_2 (OP_10760 ()); +} + +// STSR +rrrrr,111111,regID + 0000000001000000:IX:::stsr +"stsr s, r" +{ + TRACE_ALU_INPUT1 (SR[regID]); + GR[reg2] = SR[regID]; + TRACE_ALU_RESULT (GR[reg2]); +} + +// SUB +rrrrr,001101,RRRRR:I:::sub +"sub r, r" +{ + COMPAT_1 (OP_1A0 ()); +} + +// SUBR +rrrrr,001100,RRRRR:I:::subr +"subr r, r" +{ + COMPAT_1 (OP_180 ()); +} + +// SWITCH +00000000010,RRRRR:I:::switch +*v850e +*v850e1 +"switch r" +{ + unsigned long adr; + SAVE_1; + trace_input ("switch", OP_REG, 0); + adr = (cia + 2) + (State.regs[ reg1 ] << 1); + nia = (cia + 2) + (EXTEND16 (load_mem (adr, 2)) << 1); + trace_output (OP_REG); +} + +// SXB +00000000101,RRRRR:I:::sxb +*v850e +*v850e1 +"sxb r" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + GR[reg1] = EXTEND8 (GR[reg1]); + TRACE_ALU_RESULT (GR[reg1]); +} + +// SXH +00000000111,RRRRR:I:::sxh +*v850e +*v850e1 +"sxh r" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + GR[reg1] = EXTEND16 (GR[reg1]); + TRACE_ALU_RESULT (GR[reg1]); +} + +// TRAP +00000111111,iiiii + 0000000100000000:X:::trap +"trap " +{ + COMPAT_2 (OP_10007E0 ()); +} + +// TST +rrrrr,001011,RRRRR:I:::tst +"tst r, r" +{ + COMPAT_1 (OP_160 ()); +} + +// TST1 +11,bbb,111110,RRRRR + dddddddddddddddd:VIII:::tst1 +"tst1 , [r]" +{ + COMPAT_2 (OP_C7C0 ()); +} + +rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1 +*v850e +*v850e1 +"tst1 r, [r]" +{ + COMPAT_2 (OP_E607E0 ()); +} + +// XOR +rrrrr,001001,RRRRR:I:::xor +"xor r, r" +{ + COMPAT_1 (OP_120 ()); +} + +// XORI +rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori +"xori , r, r" +{ + COMPAT_2 (OP_6A0 ()); +} + +// ZXB +00000000100,RRRRR:I:::zxb +*v850e +*v850e1 +"zxb r" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + GR[reg1] = GR[reg1] & 0xff; + TRACE_ALU_RESULT (GR[reg1]); +} + +// ZXH +00000000110,RRRRR:I:::zxh +*v850e +*v850e1 +"zxh r" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + GR[reg1] = GR[reg1] & 0xffff; + TRACE_ALU_RESULT (GR[reg1]); +} + +// Right field must be zero so that it doesn't clash with DIVH +// Left field must be non-zero so that it doesn't clash with SWITCH +11111,000010,00000:I:::break +*v850 +*v850e +{ + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); +} + +11111,000010,00000:I:::dbtrap +*v850e1 +"dbtrap" +{ + DBPC = cia + 2; + DBPSW = PSW; + PSW = PSW | (PSW_NP | PSW_EP | PSW_ID); + PC = 0x00000060; + nia = 0x00000060; + TRACE_BRANCH0 (); +} + +// New breakpoint: 0x7E0 0x7E0 +00000,111111,00000 + 00000,11111,100000:X:::ilgop +{ + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); +} + +// Return from debug trap: 0x146007e0 +0000011111100000 + 0000000101000110:X:::dbret +*v850e1 +"dbret" +{ + nia = DBPC; + PSW = DBPSW; + TRACE_BRANCH1 (PSW); +} Index: v850-dc =================================================================== --- v850-dc (nonexistent) +++ v850-dc (revision 33) @@ -0,0 +1,29 @@ +# most instructions +# ------ options ------ : Fst : Lst : ff : fl : fe : word : --- fmt --- : model ... +# { : mask : value : word } + +# Top level - create a very big switch statement. + + padded-switch,combine : 15 : 5 : : : : 0 : : + + +# for opcode 60,124 + + switch,combine : 4 : 0 : : : : 1 : V,VII : + switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e + switch,combine : 4 : 0 : : : : 1 : V,XIII : v850e1 + + +# for opcode 63, 127, 1087 et.al. + + switch,combine : 9 : 5 : : : : 1 : : + switch,combine : 4 : 0 : : : : 1 : : + + +# for opcode 40 et.al. + + switch,combine : 4 : 0 : : : : 0 : III,IV : + +# for opcode 66 - divh/break + + switch,combine : 4 : 0 : : : : 0 : I : Index: ChangeLog =================================================================== --- ChangeLog (nonexistent) +++ ChangeLog (revision 33) @@ -0,0 +1,1254 @@ +2008-02-05 DJ Delorie + + * simops.c (OP_1C007E0): Compensate for 64 bit hosts. + (OP_18007E0): Likewise. + (OP_2C007E0): Likewise. + (OP_28007E0): Likewise. + * v850.igen (divh): Likewise. + + * simops.c (OP_C0): Correct saturation logic. + (OP_220): Likewise. + (OP_A0): Likewise. + (OP_660): Likewise. + (OP_80): Likewise. + + * simops.c (OP_2A0): If the shift count is zero, clear the + carry. + (OP_A007E0): Likewise. + (OP_2C0): Likewise. + (OP_C007E0): Likewise. + (OP_280): Likewise. + (OP_8007E0): Likewise. + + * simops.c (OP_2C207E0): Correct PSW flags for special divu + conditions. + (OP_2C007E0): Likewise, for div. + (OP_28207E0): Likewise, for divhu. + (OP_28007E0): Likewise, for divh. Also, sign-extend the correct + operand. + * v850.igen (divh): Likewise, for 2-op divh. + + * v850.igen (bsh): Fix carry logic. + +2007-02-20 Daniel Jacobowitz + + * Makefile.in (interp.o): Uncomment and update. + +2006-12-21 Hans-Peter Nilsson + + * acconfig.h: Remove. + * config.in: Regenerate. + +2006-06-13 Richard Earnshaw + + * configure: Regenerated. + +2006-06-05 Daniel Jacobowitz + + * configure: Regenerated. + +2006-05-31 Daniel Jacobowitz + + * configure: Regenerated. + +2005-03-23 Mark Kettenis + + * configure: Regenerate. + +2005-01-14 Andrew Cagney + + * configure.ac: Sinclude aclocal.m4 before common.m4. Add + explicit call to AC_CONFIG_HEADER. + * configure: Regenerate. + +2005-01-12 Andrew Cagney + + * configure.ac: Update to use ../common/common.m4. + * configure: Re-generate. + +2005-01-11 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2005-01-07 Andrew Cagney + + * configure.ac: Rename configure.in, require autoconf 2.59. + * configure: Re-generate. + +2004-12-08 Hans-Peter Nilsson + + * configure: Regenerate for ../common/aclocal.m4 update. + +2004-01-18 Mark Kettenis + + * simops.c: Include . + +2003-09-05 Andrew Cagney + Nick Clifton + + * interp.c (sim_open): Accept bfd_mach_v850e1. + * v850-dc: Add entry for v850e1. + * v850.igen: Add support for v850e1. + Add code for DBTRAP and DBRET instructions. + (dbtrap): Create a separate v850e1 specific instruction. + Only generate a trap if the target is not the v850e1. + Otherwise treat it as a special kind of branch. + (break): Mark as v850/v850e specific. + +2003-05-16 Ian Lance Taylor + + * Makefile.in (SHELL): Make sure this is defined. + (tmp-igen): Use $(SHELL) whenever we invoke move-if-change. + +2003-04-06 Nick Clifton + + * simops.c (OP_40): Delete. Move code to... + * v850-igen.c (): ...Here. Sign extend the first operand. + * simops.h (OP_40): Remove prototype. + +2003-02-27 Andrew Cagney + + * interp.c (sim_open, sim_create_inferior): Rename _bfd to bfd. + +2002-11-30 Andrew Cagney + + * simops.c: Use int, 1, 0 instead of boolean, true and false. + * sim-main.h: Ditto. + +2002-09-27 Jim Wilson + + * simops.c (OP_E6077E0): And op1 with 7 after reading register, not + before. + (BIT_CHANGE_OP): Likewise. + +2002-09-26 Jim Wilson + + * simops (OP_10007E0): Don't subtract 4 from PC. + +2002-09-19 Nick Clifton + + * interp.c (sim_open): Remove reference to v850ea. + (sim_create_inferior): Likewise. + * v850-dc: Likewise. + * v850.igen: Remove all references to v850ea, including v850ea + specific instructions. + +2002-08-29 Nick Clifton + + From 2001-08-23 Catherine Moore + + * Makefile.in: Add gen-zero-r0 option. + * sim-main.h (GPR_SET, GPR_CLEAR): Define. + * simops.c (OP_24007E0): Sign extend the imm9 + operand of a mul instruction. + +2002-06-17 Andrew Cagney + + * simops.c (trace_result): Fix printf formatting. + +2002-06-16 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2001-12-02 Andrew Cagney + + * Makefile.in (simops.h, table.c): Delete targets. + (tmp-gencode, gencode.o, gencode): Delete targets. + (simops.h): New file. + ($(BUILT_SRC_FROM_IGEN)): Do not depend on simops.h. + * gencode.c: Delete file. + +2001-04-15 J.T. Conklin + + * Makefile.in (simops.o): Add simops.h to dependency list. + +2001-03-14 Andrew Cagney + + * Makefile.in (gencode): Link with libintl. + +2001-01-31 Jonathan Larmour + + * Makefile.in (gencode): Link with libopcodes in build tree rather + than building source files from there. + +2000-05-30 Nick Clifton + + * v850.igen: Remove illegal instruction pattern, since it is the + same as the breakpoint pattern. + +Tue May 23 21:39:23 2000 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2000-04-14 Gary Thomas + + * v850.igen: Define 'br *' as illegal since this is the only + way to provide a breakpoint on some v850 family processors. + +2000-03-24 Frank Ch. Eigler + + * v850.igen (ilgop): New insn pattern for four-byte breakpoints. + +Thu Sep 2 18:15:53 1999 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +1999-05-08 Felix Lee + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Dec 1 17:25:16 1998 Andrew Cagney + + * Makefile.in (NL_TARGET): Define as -DNL_TARGET_v850. + +Wed Nov 25 17:52:58 1998 Andrew Cagney + + * Makefile.in (simops.o): Depends on targ-vals.h + * simops.c: Include targ-vals.h instead of + libgloss/.../syscall.h. Replace SYS_* with TARGET_SYS_*. + (divn, divun, OP_1C007E0, OP_18207E0, OP_1C207E0,OP_18007E0): + Replace signed long int with signed32. + +Fri Oct 9 18:02:25 1998 Doug Evans + + * interp.c: #include "itable.h". + (get_insn_name): New function. + (sim_open): Initialize CPU_INSN_NAME,CPU_MAX_INSNS. + * sim-main.h (MAX_INSNS,INSN_NAME): Delete. + +Wed May 6 19:43:27 1998 Doug Evans + + * sim-main.h (INSN_NAME): New arg `cpu'. + +Tue Apr 28 18:33:31 1998 Geoffrey Noer + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Sun Apr 26 15:31:55 1998 Tom Tromey + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Sun Apr 26 15:19:14 1998 Tom Tromey + + * acconfig.h: New file. + * configure.in: Reverted change of Apr 24; use sinclude again. + +Fri Apr 24 14:16:40 1998 Tom Tromey + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Fri Apr 24 11:18:08 1998 Tom Tromey + + * configure.in: Don't call sinclude. + +Sat Apr 4 20:36:25 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * sim-main.h (SIM_MAIN_H): Wrap header. + +Fri Mar 27 16:15:52 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 25 12:35:29 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Mar 10 15:54:50 1998 Andrew Cagney + + * interp.c (sim_stop): Delete, second attempt. + +Thu Feb 26 19:09:47 1998 Andrew Cagney + + * interp.c (sim_info): Delete. + +Wed Feb 18 10:47:32 1998 Andrew Cagney + + * sim-main.h (TRACE_ALU_INPUT*): Delete. Moved to sim-trace.[hc]. + + * simops.c (trace_result): Call trace_generic instead of + trace_one_insn. + (trace_module): Change variable type to integer. + (trace_input): Initialize trace_module with TRACE_ALU_IDX. + + * sim-main.h (trace_module): Change variable decl to integer type. + (TRACE_BRANCH*, TRACE_LD, TRACE_ST): Update. + +Tue Feb 17 12:51:18 1998 Andrew Cagney + + * interp.c (sim_store_register, sim_fetch_register): Pass in + length parameter. Return -1. + +Tue Feb 3 16:24:42 1998 Andrew Cagney + + * sim-main.h (IMEM16, IMEM16_IMMED): Rename IMEM and + IMEM_IMMED. To match recent igen change. + +Sun Feb 1 16:47:51 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Sat Jan 31 18:15:41 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Jan 30 09:51:27 1998 Andrew Cagney + + * sim-main.h (CPU_CIA): Delete, replaced by. + (CIA_SET, CIA_SET): Define. + +Mon Jan 19 22:26:29 1998 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Dec 15 23:17:11 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Fri Dec 5 09:26:08 1997 Nick Clifton + + * v850.igen: Revert break value back to its old value. + +Thu Dec 4 09:21:05 1997 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Dec 3 17:27:19 1997 Nick Clifton + + * v850.igen: Make break have a zero first field, since otherwise + it clashes with the DIVH instruction. + +Sat Nov 22 21:32:07 1997 Andrew Cagney + + * simops.c (OP_10007E0): Rename SIGABRT -> SIM_SIGABRT. Give + sim_stopped instead of sim_signalled. + + * v850.igen (BREAK), simops.c (OP_12007E0): Rename SIGTRAP to + SIM_SIGTRAP. + (illegal): Rename SIGILL to SIM_SIGILL. + + * sim-main.h, simops.c, interp.c: Do not include signal.h. + + * sim-main.h: Include sim-signal.h instead of signal.h. + (SIGTRAP, SIGQUIT): Delete definition. + (SIG_V850_EXIT): Delete definition. + +Tue Nov 18 15:33:48 1997 Doug Evans + + * Makefile.in (SIM_OBJS): Use $(SIM_NEW_COMMON_OBJS). + +Fri Oct 31 10:33:40 1997 Andrew Cagney + + * interp.c (sim_open): Check state magic number. + (sim-assert.h): Include. + +Tue Oct 28 11:06:47 1997 Andrew Cagney + + * v850.igen: Add model filter field to records. + +Fri Oct 3 09:28:00 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Sep 26 11:56:02 1997 Felix Lee + + * sim-main.h: delete null override of SIM_ENGINE_HALT_HOOK and + SIM_ENGINE_RESTART_HOOK. + +Wed Sep 24 17:38:57 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Sep 24 17:28:26 1997 Andrew Cagney + + * sim-main.h (WITH_TARGET_WORD_MSB): Delete. + + * configure.in (SIM_AC_OPTION_BITSIZE): Specify 32 bit + architecture with MSB == 31. + +Wed Sep 24 14:04:20 1997 Andrew Cagney + + * v850.igen: Make divh insn with RRRRR==0 breakpoint. + +Tue Sep 23 11:04:38 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Sep 23 10:19:51 1997 Andrew Cagney + + * Makefile.in (SIM_WARNINGS, SIM_ALIGNMENT, SIM_ENDIAN, + SIM_HOSTENDIAN, SIM_RESERVED_BITS): Delete, moved to common. + (SIM_EXTRA_CFLAGS): Update. + +Mon Sep 22 11:46:20 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * configure.in: Really specify NONSTRICT_ALIGNMENT as the default. + +Fri Sep 19 17:45:25 1997 Andrew Cagney + + * configure.in: Specify NONSTRICT_ALIGNMENT as the default. + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Sep 19 10:37:20 1997 Andrew Cagney + + * v850.igen (disp16): Use EXTEND16 to sign extend disp. + (disp22): Only shift left by 1, not 2. + ("jmp"): Ensure PC is 2 byte aligned. + + * simops.c, v850.igen: Move "Bcond", "jr", "jarl" code to + v850.igen. Fix tracing. + + * simops.c (OP_300, OP_400, OP_500): Move "sdl.b", "sld.h", + "sld.w" insns to v850.igen. Fix tracing. + (OP_70): Ditto for "sld.hu". + + * v850.igen: Clarify tracing of "sld.b", "sld.h" et.al. + + * simops.c (condition_met): Make global. + + * sim-main.h (TRACE_ALU_INPUT3, TRACE_BRANCH0, TRACE_LD, + TRACE_ST): Define. + (TRACE_LD_NAME): Define. + + * simops.c: Move "cmov", "cmov imm" to v850.igen, fix. + +Wed Sep 17 16:21:08 1997 Andrew Cagney + + * simops.c: Move "mov", "reti", to v850.igen, fix tracing. + + * interp.c (hash): Delete. + + * v850.igen (nop): Really do nothing. + + * interp.c (do_interrupt): Mask interrupts after PSW is saved, not + before. + * v850.igen (reti): Return to current PC not previous. + +Wed Sep 17 14:02:10 1997 Andrew Cagney + + * simops.c: Move "ctret", "bsw", "hsw" to v850.igen, fix tracing. + (trace_module): Global, save component/module name across insn. + + * simops.c: Move "bsh" to v850.igen, fix. + + * v850.igen (callt): Load correct number of bytes. Fix tracing. + (stsr, ldsr): Correct src, dest fields. Fix tracing. + (ctret): Force alignment. Fix tracing. + +Tue Sep 16 22:14:01 1997 Andrew Cagney + + * simops.c (trace_output): Add result argument. + (trace_result): New function. Simpler version of trace_output, + assumes trace needed. + (trace_output): Call trace_result. + (trace_output): For IMM_REG_REG, trace correct register. + (trace_input): Add case for 16bit immediates. + (OP_600, OP_640, OP_680, OP_6C0, OP_6A0): Use. + + * sim-main.h (TRACE_ALU_INPUT, TRACE_ALU_RESULT): Define. + (trace_values, trace_name, trace_pc, trace_num_values): Make + global. + (GR, SR): Define. + + v850.insn (movea, stsr): Use. + (sxb, sxh, zxb, zxh): Ditto. + +Tue Sep 16 21:14:01 1997 Andrew Cagney + + * simops.c: Move "movea" from here. + * v850.igen: To here. + + * v850.igen (simm16): Define, sign extend imm16. + (uimm16): Define, no sign extension. + (addi, andi, movea, movhi, mulhi, ori, satsubi, xori): Use. + + * simops.c: Move "sxh", "switch", "sxb", "callt", "dispose", + "mov32" from here. + * v850.igen: To here. + (switch): Fix off by two error in NIA calc. + +Tue Sep 16 15:14:01 1997 Andrew Cagney + + * simops.c (trace_pc, trace_name, trace_values, trace_num_values): + New static globals. + (trace_input): Just save pc, name and values for trace_output. + (trace_output): Write trace values to a buffer. Use + trace_one_insn to print trace info and buffer. + (SIZE_OPERANDS, SIZE_LOCATION): Delete. + +Tue Sep 16 09:02:00 1997 Andrew Cagney + + * sim-main.h (struct _sim_cpu): Add psw_mask so that reserved bits + can be masked out. + + * simops.c (OP_2007E0, OP_4007E0): Move "ldsr", "stsr" + instructions from here. + * v850.igen (ldsr, stsr): To here. Mask out reserved bits when + setting PSW. + + * interp.c (sim_open): Set psw_mask if machine known. + +Tue Sep 16 10:20:00 1997 Andrew Cagney + + * v850-dc: Add rule to diferentiate between breakpoint and divh. + * v850.igen (break): New instruction, breakpoint simulator. + * v850.igen (breakpoint): Enable. Change to a 32bit instruction. + +Mon Sep 15 18:44:05 1997 Jim Wilson + + * simops.c (Multiply64): Don't store into register zero. + +Tue Sep 16 09:02:00 1997 Andrew Cagney + + * Makefile.in (semantics.o): Add dependency. + + * sim-main.h (SAVE_1, SAVE_2): Perform backward compatible save, + do not adjust CIA/NIA. + +Mon Sep 15 17:36:15 1997 Andrew Cagney + + * simops.c (OP_300, OP_400, OP_70): Make behavour depend on PSW[US]. + + * simops.c: Move "divun", "sld.bu", "divhn", "divhun", "divn", + "divun", "pushml" code from here to v850.igen. + (divun): Make global. + (type3_regs): Make global + + * v850.igen: Move simops.c code to here. + + * interp.c (sim_create_inferior): For v850eq set US bit by + default. + + * interp.c (sim_open): Don't set arch, now set by + sim_analyze_program. + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Sep 15 14:39:34 1997 Andrew Cagney + + * simops.c (op_types): Move from here. + sim-main.h: To here. + + * sim-main.h (trace_input, trace_output), simops.c: Make global. + + * simops.c (OP_60): Move "jmp" code from here. + * v850.igen (jmp): To here. + + * simops.c (OP_60): Move "sld.bu" code from here. + * v850.igen (sld.bu): To here. + +Fri Sep 12 15:11:03 1997 Andrew Cagney + + * v850.igen (prepare, ...): Add to v850eq architecture. + + * interp.c (sim_open): Default to v850eq. + + * interp.c (sim_open): Default to v850e. + * sim-main.h (signal.h): Include. + + * v850.igen (illegal): Report/halt illegal instructions. + + * Makefile.in (SIM_EXTRA_CFLAGS): Add SIM_RESERVED_BITS. + + * configure.in: Add reserved bits option. + * configure: Regenerate. + +Thu Sep 11 08:40:03 1997 Andrew Cagney + + * interp.c (sim_open): Use sim_do_commandf instead of asprintf. + + * sim-main.h (INSN_NAME): + + * Makefile.in (INCLUDE): Add SIM_EXTRA_DEPS. + (SIM_EXTRA_DEPS): Add itable.h + (tmp-gencode): Does not depend on simops.h + + * sim-main.h (itable.h): Include. + (MAX_INSNS, INSN_NAME): Define. + + * interp.c: Compute inttype from the interrupt_names index that + was passed in. + +Wed Sep 10 10:25:40 1997 Andrew Cagney + + * simops.c (trace_input): Use trace_printf instead of + sim_io_printf. + (trace_output): Ditto. + (trace_input): Only trace when TRACE_ALU_P. Delete code + disasembling instruction. + (trace_output): Only trace when TRACE_ALU_P. + +Tue Sep 9 01:29:50 1997 Andrew Cagney + + * simops.c (trace_input, trace_output): Use sim_io_printf. + (OP_620): Pass correct argument to trace. + (OP_E607E0): Ditto. + (trace_input): Obtain prog_bfd, text_start et.al from simulator + struct. + +Mon Sep 8 21:03:52 1997 Andrew Cagney + + * v850.igen: New file. + * v850-dc: New file. + +Mon Sep 8 18:33:04 1997 Andrew Cagney + + + * sim-main.h (SEXT16): Delete, use EXTEND16. + (SEXT8): Delete, use EXTEND8. + (SEXT32): Delete, used? + (SEXT40, SEXT44, SEXT64): Use UNSIGNED64 for constants, not ...LL. + (WITH_TARGET_WORD_MSB): Define as 31. v850 little bit endian. + + * simops.c: Use EXTEND15 from sim-bits instead of SEXT16. + + * sim-main.h (DEBUG_TRACE, DEBUG_VALUES, v850_debug): Delete, + replace with TRACE_INSN_P and TRACE_ALU_P. + + * simops.c (trace_input, trace_output): Update. + + * interp.c (sim_engine_run): Delete. + (lookup_hash): Delete. + (sim_open): Do not fill hash table. + (sim_trace): Delete. + +Fri Sep 5 17:04:48 1997 Andrew Cagney + + * simops.c (OP_FFFF): Use sim_engine_halt. + (OP_12007E0): Ditto. + (OP_10007E0): Ditto. + + * sim-main.h (struct sim_cpu): Delete member exception. Using + sim-engine et.al. + + * interp.c (sim_info): Do not do anything in sim-info. + (sim_stop): Delete, replace with sim-stop. + (sim_stop_reason): Delete, replace with sim-reason. + + * sim-main.h (WITH_WATCHPOINTS): Define. + (WITH_MODULO_MEMORY): Define + + * Makefile.in (SIM_OBJS): Add sim-resume, sim-watch, sim-stop, + sim-reason. + + * interp.c (enum interrupt_cond_type): Delete. + (struct interrupt_generator): Delete. + (enum interrupt_type): Drop int_none. + (sim_open): Initialize WATCHPOINT module. + (sim_resume, sim_run): Rename sim_resume to sim_run. + (sim_engine_run): Replace interrupt code with call to sim-events. + (sim_set_interrupt): Delete. + (sim_parse_number): Delete. + +Thu Sep 4 17:21:23 1997 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Thu Sep 4 18:11:37 1997 Andrew Cagney + + * simops.c (fetch_argv): New function, fetch a arg vector from + simulator memory. + + * configure.in: Check for fork, execve, execv. + * configure: Regenerate. + + * interp.c (sim_store_register, sim_fetch_register): Use H2T_4 and + T2H_4 for byte swapping. + + * sim-main.h, interp.c (get_word, get_half, get_byte, put_word, + put_half, put_byte): Delete. + + * Makefile.in (SIM_OBJS): Add sim-memopt.o module. + + * sim-main.h (load_mem, store_mem): Redefine as macros. + (IMEM, IMEM_IMMED): New macros - fetch instructions. + + * simops.c (OP_10007E0): For SYS_read, SYS_write, SYS_open + transfer data via a buffer. + (fetch_str): New function, fetch string from memory. + + * Makefile.in (SIM_OBJS): Add sim-hrw.o module. + + * interp.c (sim_open): Establish memory maps using sim-memopt.c + via sim_do_command. + (sim_do_command): Print error if memory-map command is used. Call + sim_args_command. + (map): Delete, replaced by sim-core. + (sim_memory_init): Delete, replaced by sim-core. + (sim_set_memory_map): Delete, replaced by sim-memopt. + (load_mem): Delete, replaced by sim-core. + (store_mem): Delete, replaced by sim-core. + (sim_write): Delete, replaced by sim-hrw. + (sim_read): Delete, replaced by sim-hrw. + + * sim-main.h (struct sim_state): Remove memory members, using + sim-core.c + +Wed Sep 3 10:18:55 1997 Andrew Cagney + + * sim-main.h: Replace SIM_HAVE_FLATMEM with mem ptr. + * interp.c (map): Do not add to a void pointer. + + * Makefile.in (INCLUDE): Add sim-main.h + + * configure.in: Check for time.h + * configure: Re-generate. + + * interp.c (struct interrupt_generator): Make time unsigned long, + address SIM_ADDR. + (sim_resume): Make oldpc SIM_ADDR. + (struct hash_entry): Make mask/opcode unsigned. + + * v850_sim.h (struct simops ): Make opcode and mask unsigned. + + * simops.c (utime.h): Include if available. + (OP_10007E0): Check for UTIME function. + (divun): Put parentheses around shift argument. + (OP_640): Put parentheses around shift argument, was wrong. + (OP_107F0): Return something. + + * interp.c (sim_parse_number): Use strtoul not strtol. + (sim_resume): Use sim_elapsed_time_get to keep track of the time. + + * configure.in (SIM_AC_OPTION_WARNINGS): Add. + (SIM_AC_OPTION_ENDIAN): Set to hardwired big. + (SIM_AC_OPTION_HOST_ENDIAN): Add. + (AC_CHECK_FUNCS): Add utime. + (AC_CHECK_HEADERS): Add stdlib.h, string.h, strings.h, utime.h + configure: Regenerate. + + + * Makefile.in (SIM_RUN_OBJS): Use nrun.o. + (SIM_OBJS): Add sim-io.o, sim-hload.o, sim-utils.o, sim-options.o, + sim-config.o, sim-module.o, sim-events.o, sim-core.o, + sim-endian.o, sim-engine.o, sim-trace.o, sim-profile.o + (SIM_ENDIAN, SIM_WARNGINS): Define. + + * simops.c (OP_10007E0): Use sim_io_* for transfers. + + * interp.c (sim_resume): Pass sd around. + + * simops.c (sim-main.h): Include. + + * gencode.c (write_template): Generate #include sim-main.h. + (write_opcodes): Ditto. + + * interp.c (prog_bfd, prog_bfd_was_opened_p): Delete. + (v850_callback): Ditto. + (sim_kind, myname): Ditto. + (lookup_hash): Pass SD. Use sim_io_error. + (sim_set_memory_map): Pass in SD, use. + (init_system): Pass in SD, use. + (sim_open): Update. + (sim_set_profile): Delete. + (sim_set_profile_size): Delete. + (do_interrupt): Pass in SD, use. + (sim_info): Use sim_io_printf. + (sim_create_inferior): Reset registers. Set PC from prog_bfd + argument. + (sim_load): Delete, use common/sim-hload.c + (sim_size): Rename to sim_memory_init. + (sim_write): Remove call to init_system. + (init_system): Delete. + (sim_set_callbacks): Delete. + (sim_set_interrupt): Pass in SD, use. + (start_time): Delete. + + * v850_sim.h: Remove everything except `struct simops' from here. + * sim-main.h: Move most to here. + * gencode.c: Move #includes to here. + + * sim-main.h(struct _sim_cpu): Rename struct _state. + (#define PC, et.al.): Update + (v850_callback): Delete. Replaced with SIM_DESC arg. + (int8, uint8, int16, uint16, int32, uint32): Define types using + unsigned8 et.al from common/sim-types.h. + * sim-main.h (State): Define as STATE_CPU. + +Mon Sep 1 12:07:55 1997 Andrew Cagney + + * configure.in: Check for time, chmod. + * configure: Regenerate. + * simops.c (SYS_time, SYS_chmod): Use HAVE_TIME, HAVE_CHMOD. + + * simops.c (../../libgloss/v850/sys/syscall.h): Include instead of + sys/syscall.h. + (OP_10007E0): Check the existance each SYS_* macro independantly. + + * v850_sim.h (SIGQUIT, SIGTRAP): Only define if missing. + +Wed Aug 27 18:13:22 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Tue Aug 26 10:42:38 1997 Andrew Cagney + + * interp.c (sim_kill): Delete. + (sim_create_inferior): Add ABFD argument. + (sim_load): Move setting of PC from here. + (sim_create_inferior): To here. + +Mon Aug 25 17:50:22 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Mon Aug 25 11:31:23 1997 Andrew Cagney + + * interp.c (sim_open): Add ABFD argument. + +Fri Aug 22 10:39:28 1997 Nick Clifton + + * simops.c (bsh): Only set CY flag if either of the bottom + bytes is zero. + + * simops.c (prepare, dispose): Lower numbered + registers go to higher numbered address. + + * simops.c (unsigned divide instructions): S bit set if result has + top bit set. + + * simops.c (pushml, pushmh, popml, popmh): Lower numbered + registers go to higher numbered address. + +Wed Aug 20 13:56:35 1997 Nick Clifton + + * simops.c (OP_107E0, OP_107F0, OP_307E0, OP_307F0): Use correct + interpretation of SR bit in list18 structure. + (divn, divun): New functions to perform N step divide functions. + +Mon Aug 18 10:59:02 1997 Nick Clifton + + * simops.c (OP_300, OP_400, OP_60, OP_70): Support variant opcodes + with US bit set in the PSW. + +Wed Aug 13 19:06:55 1997 Nick Clifton + + * interp.c (sim_resume): Opcode functions return amount to be + added to PC and all opcodes take a standard format in the OP[] + array. + + (do_format_*): Functions removed. + + * v850_sim.h (SP, EP): New register mnemonics. + + * gencode.c (write_header): Functions prototypes return an + integer. + + * simops.c: Opcode functions return amount to be added to PC. + + * v850_sim.h (CTPC, CTPSW, CTBP): New register mnemonics. + + * simops.c: Add support for v850e instructions. + + * simops.c: Add support for v850eq instructions. + +Tue May 20 10:24:14 1997 Andrew Cagney + + * interp.c (sim_open): Add callback argument. + (sim_set_callbacks): Delete SIM_DESC argument. + +Thu Apr 24 00:39:51 1997 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Apr 23 17:20:16 1997 Doug Evans + + * interp.c (prog_bfd_was_opened_p): New static local. + (prog_bfd): New global variable. + (sim_open): Undo patch to add -E support. + (sim_close): Close prog_bfd if sim_load opened it. + (sim_load): Record bfd of loaded file in prog_bfd. + * simops.c (prog_bfd): Renamed from exec_bfd. + +Fri Apr 18 14:17:12 1997 Andrew Cagney + + * interp.c (sim_stop): Stub function. + +Thu Apr 17 03:53:18 1997 Doug Evans + + * Makefile.in (SIM_OBJS): Add sim-load.o. + * interp.c (sim_kind, myname): New static locals. + (sim_open): Set sim_kind, myname. Ignore -E arg. + (sim_load): Return SIM_RC. New arg abfd. Call sim_load_file to + load file into simulator. Set start address from bfd. + (sim_create_inferior): Return SIM_RC. Delete arg start_address. + +Wed Apr 16 19:53:55 1997 Andrew Cagney + + * simops.c (OP_10007E0): Only provide system calls SYS_execv, + SYS_wait, SYS_wait, SYS_utime, SYS_time if defined by the host. + +Mon Apr 7 15:45:02 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Wed Apr 2 15:06:28 1997 Doug Evans + + * interp.c (sim_open): New arg `kind'. + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Apr 2 14:34:19 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 19 01:14:00 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Mar 17 15:10:07 1997 Andrew Cagney + + * configure: Re-generate. + +Fri Mar 14 10:34:11 1997 Michael Meissner + + * configure: Regenerate to track ../common/aclocal.m4 changes. + +Thu Mar 13 13:00:54 1997 Doug Evans + + * interp.c (sim_open): New SIM_DESC result. Argument is now + in argv form. + (other sim_*): New SIM_DESC argument. + +Tue Feb 4 13:33:30 1997 Doug Evans + + * Makefile.in (@COMMON_MAKEFILE_FRAG): Use + COMMON_{PRE,POST}_CONFIG_FRAG instead. + * configure.in: sinclude ../common/aclocal.m4. + * configure: Regenerated. + +Thu Jan 23 11:46:23 1997 Stu Grossman (grossman@critters.cygnus.com) + + * configure configure.in Makefile.in: Update to new configure + scheme which is more compatible with WinGDB builds. + * configure.in: Improve comment on how to run autoconf. + * configure: Re-run autoconf to get new ../common/aclocal.m4. + * Makefile.in: Use autoconf substitution to install common + makefile fragment. + +Mon Jan 20 16:05:34 1997 Michael Meissner + + * simops.c (OP_{E0,2E0,6E0}): The multiply operations sign extend, + not zero extend. + +Tue Jan 14 17:06:03 1997 Stu Grossman (grossman@critters.cygnus.com) + + * simops.c: Put ifdefs around things to make MSVC happy. Get rid + of unistd.h. Disable SYS_stat, SYS_chown, SYS_time, SYS_times, + SYS_gettimeofday and SYS_utime from MSVC. + +Tue Dec 31 18:11:13 1996 Michael Meissner + + * simops.c (OP_10007E0): Know that kill encodes the signal number + via: 0xdead0000 | signal and turn it back into a signal. + +Fri Dec 27 14:44:06 1996 Michael Meissner + + * v850_sim.h (SIG_V850_EXIT): Define as -1. + + * interp.c (sim_open): Cast calloc function. + (sim_stop_reason): If signal is SIG_V850_EXIT, inform gdb the + program exited with the appropriate exit code. + (sim_set_interrupt): Declare buildargv. + + * simops.c (OP_10007E0): Make exit signal normal exit. Make time + type correct and work on big endian systems. + +Wed Nov 20 02:18:44 1996 Doug Evans + + * Makefile.in: Delete stuff moved to ../common/Make-common.in. + (SIM_OBJS,SIM_EXTRA_CFLAGS,SIM_EXTRA_CLEAN): Define. + * configure.in: Simplify using macros in ../common/aclocal.m4. + Call AC_CHECK_HEADERS(unistd.h). + * configure: Regenerated. + * config.in: New file. + * simops.c: #include "config.h". #include if present. + +Sun Nov 3 23:02:54 1996 Stan Shebs + + * v850_sim.h (State): New slots dummy_mem, pending_nmi. + (EIPC, etc): New macros for system registers. + * simops.c, interp.c: Use everywhere. + + * interp.c: Add support for interrupts issued by interrupt + generators, either PC- or time-based. Controlled by simulator + command "sim interrupt". + + * interp.c: Add support for variable-size allocation of memory, + via simulator command "sim memory-map". + (map): Issue SIGSEGV for references to invalid memory regions. + +Thu Oct 31 14:44:10 1996 Gavin Koch + + * simops.c: Include for struct timeval and + struct timezone. + +Wed Oct 30 08:49:10 1996 Jeffrey A Law (law@cygnus.com) + + * simops.c (OP_10007E0): Handle SYS_times and SYS_gettimeofday. + + * simops.c (OP_10007E0): Handle SYS_time. + +Tue Oct 29 14:22:55 1996 Jeffrey A Law (law@cygnus.com) + + * simops.c: Include . + (OP_10007E0): Handle SYS_stat. + +Thu Oct 24 12:26:35 1996 Jeffrey A Law (law@cygnus.com) + + * simops.c (OP_10007E0): Don't declare errno. + + * simops.c (OP_500): Mask off low bit in displacement + for sld.w. + (OP_501): Similarly. + + * simops.c (OP_500): Fix displacement handling for sld.w. + (OP_501): Similarly for sst.w. + + * simops.c (trace_input): Remove all references to SEXT7. + (OP_300, OP_400, OP_500, OP_380, OP_480, OP_501): Displacement + is zero extended for sst/sld instructions. + * v850_sim.h (SEX7): Delete. It's no longer needed (and it + was incorrect anyway). + +Thu Oct 24 10:33:33 1996 Stu Grossman (grossman@critters.cygnus.com) + + * Makefile.in: Get rid of srcroot. Set all INSTALL macros via + autoconf. + * gencode.c (write_opcodes): Pad operands field to account for + MSVC braindamage. + * simops.c: Include errno.h. Exclude SYS_chown, since MSVC + doesn't support it. (Why is this here in the first place?!?) + * v850_sim.h: Get rid of 64 bit defs. Also, get rid of #elif's. + Change number of operands in struct simops from 9 to 6. Define + SIGTRAP and SIGQUIT for MSVC. + +Tue Oct 15 16:19:51 1996 Stu Grossman (grossman@critters.cygnus.com) + + * interp.c (MEM_SIZE): It's now bytes, not a power of 2. + * (map): Add support for external mem in the 1->2 meg range. + Also, abort() when memory access is way out of bounds. (Better to + die than to give wrong result. (This will be fixed later.)) + * (sim_size): MEM_SIZE is now bytes, not shift factor. + +Tue Oct 1 15:53:24 1996 Gavin Koch + + * simops.c (trace_input): Swapped order of operands for output + output of OP_IMM_REG. Changed the fetching of the operands for + OP_LOAD32, and OP_STORE32 to work like op-function. + +Mon Sep 30 15:46:33 1996 Stu Grossman (grossman@critters.cygnus.com) + + * interp.c: Move includes of remote-sim.h and callback.h to + v850-sim.h. + * (lookup_hash): Add PC to report of hash failure. + * (map load_mem store_mem): New memory subsystem. Models V851 + memory system. + * (sim_write sim_read): Use new memory subsystem. + * (sim_resume): Don't load and save PC into EIPC anymore. Needed + to make user-defined traps work right. + * simops.c (OP_*): Use new memory subsystem. + * (OP_14007E0 (reti)): Implement reti. + * (OP_14996E0 (trap)): Implement user-defined traps. Move I/O to + trap 31. Use new memory subsystem. + * v850_sim.h: Prototypes for load_mem, store_mem and map. Use + load_mem in RLW macro. + +Fri Sep 27 18:34:09 1996 Stu Grossman (grossman@critters.cygnus.com) + + * gencode.c (write_opcodes): Output hex values for opcode mask + and patterns. + * interp.c (sim_resume): Save and restore PC from the appropriate + register. + * (sim_fetch_register sim_store_register): Fix byte-order problem + with reading and writing registers. + * simops.c (OP_FFFF): Implement pseudo-breakpoint insn. + +Fri Sep 27 17:42:37 1996 Jeffrey A Law (law@cygnus.com) + + * simops.c (trace_input): Fix thinko. + +Wed Sep 18 09:54:12 1996 Michael Meissner + + * simops.c (exec_bfd): Rename from sim_bfd. + (trace_input): Ditto. + +Thu Sep 12 12:03:05 1996 Michael Meissner + + * simops.c (trace_input): Use find_nearest_line to print line + number, function name or file name of PC. + +Wed Sep 11 16:44:37 1996 Michael Meissner + + * simops.c: Add tracing support. Use SEXTxx macros instead of + doing hardwired shifts. + + * configure.in (--enable-sim-cflags): Add switch to add additional + flags to simulator buld. If --enable-sim-cflags=trace, turn on + tracing. + * configure: Regenerate. + + * Makefile.in: Don't require a VPATH capable make if configuring + in the same directory. Don't use CFLAGS for configuration flags. + Add flags from --enable-sim-cflags. Support canadian cross + builds. Rebuild whole simulator if include files change. + + * interp.c (v850_debug): New global for debugging. + (lookup_hash,sim_size,sim_set_profile): Use + printf_filtered callback, instead of calling printf directly. + (sim_{open,trace}): Enable tracing if -t and compiled for tracing. + + * v850_sim.h: Use limits.h to set the various sized types. + (SEXT{5,7,16,22}): New macros. + +Mon Sep 9 20:50:46 1996 Jeffrey A Law (law@cygnus.com) + + * interp.c (hash): Make this an inline function + when compiling with GCC. Simplify. + * simpos.c: Explicitly include "sys/syscall.h". Remove + some #if 0'd code. Enable more emulated syscalls. + +Wed Sep 4 01:48:55 1996 Jeffrey A Law (law@cygnus.com) + + * interp.c: Fix sign bit handling for add and sub instructions. + +Tue Sep 3 10:20:30 1996 Jeffrey A Law (law@cygnus.com) + + * gencode.c: Fix various indention & style problems. + Remove test code. Remove #if 0 code. + * interp.c: Provide prototypes for all static functions. + Fix minor indention problems. + (sim_open, sim_resume): Remove unused variables. + (sim_read): Return type is "int". + * simops.c: Remove unused variables. + (divh): Make result of divide-by-zero zero. + (setf): Initialize result to keep compiler quiet. + (sar instructions): These just clear the overflow bit. + * v850_sim.h: Provide prototypes for put_byte, put_half + and put_word. + + * interp.c: OP should be an array of 32bit operands! + (v850_callback): Declare. + (do_format_5): Fix extraction of OP[0]. + (sim_size): Remove debugging printf. + (sim_set_callbacks): Do something useful. + (sim_stop_reason): Gross hacks to get c-torture running. + * simops.c: Simplify code for computing targets of bCC + insns. Invert 's' bit if 'ov' bit is set for some + instructions. Fix 'cy' bit handling for numerous + instructions. Make the simulator stop when a halt + instruction is encountered. Very crude support for + emulated syscalls (trap 0). + * v850_sim.h: Include "callback.h" and declare + v850_callback. Items in the operand array are 32bits. + +Sun Sep 1 22:35:35 1996 Jeffrey A Law (law@cygnus.com) + + * interp.c (sim_resume): Fix code to check for a format 3 + opcode. + * simops.c: bCC insns only argument is a constant, not a + register value (duh...) + +Fri Aug 30 10:33:49 1996 Jeffrey A Law (law@cygnus.com) + + * simops.c: Fix "not1" and "set1". + + * simops.c: Don't forget to initialize temp for + "ld.h" and "ld.w" + + * interp.c: Remove various debugging printfs. + + * simops.c: Fix satadd, satsub boundary case handling. + + * interp.c (hash): Fix. + * interp.c (do_format_8): Get operands correctly and + call the target function. + * simops.c: Rough cut at "clr1", "not1", "set1", and "tst1". + +Thu Aug 29 13:53:29 1996 Jeffrey A Law (law@cygnus.com) + + * interp.c (do_format_4): Get operands correctly and + call the target function. + * simops.c: Rough cut at "sld.b", "sld.h", "sld.w", "sst.b", + "sst.h", and "sst.w". + + * v850_sim.h: The V850 doesn't have split I&D spaces. Change + accordingly. Remove many unused definitions. + * interp.c: The V850 doesn't have split I&D spaces. Change + accordingly. + (get_longlong, get_longword, get_word): Deleted. + (write_longlong, write_longword, write_word): Deleted. + (get_operands): Deleted. + (get_byte, get_half, get_word): New functions. + (put_byte, put_half, put_word): New functions. + * simops.c: Remove unused functions. Rough cut at + "ld.b", "ld.h", "ld.w", "st.b", "st.h", "st.w" insns. + + * v850_sim.h (struct _state): Remove "psw" field. Add + "sregs" field. + (PSW): Remove bogus definition. + * simops.c: Change condition code handling to use the psw + register within the sregs array. Handle "ldsr" and "stsr". + + * simops.c: Handle "satadd", "satsub", "satsubi", "satsubr". + + * interp.c (do_format_5): Get operands correctly and + call the target function. + (sim_resume): Don't do a PC update for format 5 instructions. + * simops.c: Handle "jarl" and "jmp" instructions. + + * simops.c: Fix minor typos. Handle "cmp", "setf", "tst" + "di", and "ei" instructions correctly. + + * interp.c (do_format_3): Get operands correctly and call + the target function. + * simops.c: Handle bCC instructions. + + * simops.c: Add condition code handling to shift insns. + Fix minor typos in condition code handling for other insns. + + * Makefile.in: Fix typo. + * simops.c: Add condition code handling to "sub" "subr" and + "divh" instructions. + + * interp.c (hash): Update to be more accurate. + (lookup_hash): Call hash rather than computing the hash + code here. + (do_format_1_2): Handle format 1 and format 2 instructions. + Get operands correctly and call the target function. + (do_format_6): Get operands correctly and call the target + function. + (do_formats_9_10): Rough cut so shift ops will work. + (sim_resume): Tweak to deal with format 1 and format 2 + handling in a single funtion. Don't update the PC + for format 3 insns. Fix typos. + * simops.c: Slightly reorganize. Add condition code handling + to "add", "addi", "and", "andi", "or", "ori", "xor", "xori" + and "not" instructions. + * v850_sim.h (reg_t): Registers are 32bits. + (_state): The V850 has 32 general registers. Add a 32bit + psw and pc register too. Add accessor macros + + * Makefile.in, interp.c, v850_sim.h: Bring over endianness + changes from the d10v simulator. + + * simops.c: Add shift support. + + * simops.c: Add multiply & divide support. Abort for system + instructions. + + * simops.c: Add logicals, mov, movhi, movea, add, addi, sub + and subr. No condition codes yet. + +Wed Aug 28 13:53:22 1996 Jeffrey A Law (law@cygnus.com) + + * ChangeLog, Makefile.in, configure, configure.in, v850_sim.h, + gencode.c, interp.c, simops.c: Created. +
ChangeLog Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: config.in =================================================================== --- config.in (nonexistent) +++ config.in (revision 33) @@ -0,0 +1,117 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to 1 if you have the `chmod' function. */ +#undef HAVE_CHMOD + +/* Define to 1 if you have the `chown' function. */ +#undef HAVE_CHOWN + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the `execv' function. */ +#undef HAVE_EXECV + +/* Define to 1 if you have the `execve' function. */ +#undef HAVE_EXECVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_FPU_CONTROL_H + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the `time' function. */ +#undef HAVE_TIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `utime' function. */ +#undef HAVE_UTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define to 1 if you have the `__setfpucw' function. */ +#undef HAVE___SETFPUCW + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN Index: simops.c =================================================================== --- simops.c (nonexistent) +++ simops.c (revision 33) @@ -0,0 +1,2763 @@ +#include "sim-main.h" +#include "v850_sim.h" +#include "simops.h" + +#include + +#ifdef HAVE_UTIME_H +#include +#endif + +#ifdef HAVE_TIME_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#include "targ-vals.h" + +#include "libiberty.h" + +#include +#if !defined(__GO32__) && !defined(_WIN32) +#include +#include +#include +#endif + +/* This is an array of the bit positions of registers r20 .. r31 in + that order in a prepare/dispose instruction. */ +int type1_regs[12] = { 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 0, 21 }; +/* This is an array of the bit positions of registers r16 .. r31 in + that order in a push/pop instruction. */ +int type2_regs[16] = { 3, 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21}; +/* This is an array of the bit positions of registers r1 .. r15 in + that order in a push/pop instruction. */ +int type3_regs[15] = { 2, 1, 0, 27, 26, 25, 24, 31, 30, 29, 28, 23, 22, 20, 21}; + +#ifdef DEBUG +#ifndef SIZE_INSTRUCTION +#define SIZE_INSTRUCTION 18 +#endif + +#ifndef SIZE_VALUES +#define SIZE_VALUES 11 +#endif + + +unsigned32 trace_values[3]; +int trace_num_values; +unsigned32 trace_pc; +const char *trace_name; +int trace_module; + + +void +trace_input (name, type, size) + char *name; + enum op_types type; + int size; +{ + + if (!TRACE_ALU_P (STATE_CPU (simulator, 0))) + return; + + trace_pc = PC; + trace_name = name; + trace_module = TRACE_ALU_IDX; + + switch (type) + { + default: + case OP_UNKNOWN: + case OP_NONE: + case OP_TRAP: + trace_num_values = 0; + break; + + case OP_REG: + case OP_REG_REG_MOVE: + trace_values[0] = State.regs[OP[0]]; + trace_num_values = 1; + break; + + case OP_BIT_CHANGE: + case OP_REG_REG: + case OP_REG_REG_CMP: + trace_values[0] = State.regs[OP[1]]; + trace_values[1] = State.regs[OP[0]]; + trace_num_values = 2; + break; + + case OP_IMM_REG: + case OP_IMM_REG_CMP: + trace_values[0] = SEXT5 (OP[0]); + trace_values[1] = OP[1]; + trace_num_values = 2; + break; + + case OP_IMM_REG_MOVE: + trace_values[0] = SEXT5 (OP[0]); + trace_num_values = 1; + break; + + case OP_COND_BR: + trace_values[0] = State.pc; + trace_values[1] = SEXT9 (OP[0]); + trace_values[2] = PSW; + trace_num_values = 3; + break; + + case OP_LOAD16: + trace_values[0] = OP[1] * size; + trace_values[1] = State.regs[30]; + trace_num_values = 2; + break; + + case OP_STORE16: + trace_values[0] = State.regs[OP[0]]; + trace_values[1] = OP[1] * size; + trace_values[2] = State.regs[30]; + trace_num_values = 3; + break; + + case OP_LOAD32: + trace_values[0] = EXTEND16 (OP[2]); + trace_values[1] = State.regs[OP[0]]; + trace_num_values = 2; + break; + + case OP_STORE32: + trace_values[0] = State.regs[OP[1]]; + trace_values[1] = EXTEND16 (OP[2]); + trace_values[2] = State.regs[OP[0]]; + trace_num_values = 3; + break; + + case OP_JUMP: + trace_values[0] = SEXT22 (OP[0]); + trace_values[1] = State.pc; + trace_num_values = 2; + break; + + case OP_IMM_REG_REG: + trace_values[0] = EXTEND16 (OP[0]) << size; + trace_values[1] = State.regs[OP[1]]; + trace_num_values = 2; + break; + + case OP_IMM16_REG_REG: + trace_values[0] = EXTEND16 (OP[2]) << size; + trace_values[1] = State.regs[OP[1]]; + trace_num_values = 2; + break; + + case OP_UIMM_REG_REG: + trace_values[0] = (OP[0] & 0xffff) << size; + trace_values[1] = State.regs[OP[1]]; + trace_num_values = 2; + break; + + case OP_UIMM16_REG_REG: + trace_values[0] = (OP[2]) << size; + trace_values[1] = State.regs[OP[1]]; + trace_num_values = 2; + break; + + case OP_BIT: + trace_num_values = 0; + break; + + case OP_EX1: + trace_values[0] = PSW; + trace_num_values = 1; + break; + + case OP_EX2: + trace_num_values = 0; + break; + + case OP_LDSR: + trace_values[0] = State.regs[OP[0]]; + trace_num_values = 1; + break; + + case OP_STSR: + trace_values[0] = State.sregs[OP[1]]; + trace_num_values = 1; + } + +} + +void +trace_result (int has_result, unsigned32 result) +{ + char buf[1000]; + char *chp; + + buf[0] = '\0'; + chp = buf; + + /* write out the values saved during the trace_input call */ + { + int i; + for (i = 0; i < trace_num_values; i++) + { + sprintf (chp, "%*s0x%.8lx", SIZE_VALUES - 10, "", + (long) trace_values[i]); + chp = strchr (chp, '\0'); + } + while (i++ < 3) + { + sprintf (chp, "%*s", SIZE_VALUES, ""); + chp = strchr (chp, '\0'); + } + } + + /* append any result to the end of the buffer */ + if (has_result) + sprintf (chp, " :: 0x%.8lx", (unsigned long)result); + + trace_generic (simulator, STATE_CPU (simulator, 0), trace_module, buf); +} + +void +trace_output (result) + enum op_types result; +{ + if (!TRACE_ALU_P (STATE_CPU (simulator, 0))) + return; + + switch (result) + { + default: + case OP_UNKNOWN: + case OP_NONE: + case OP_TRAP: + case OP_REG: + case OP_REG_REG_CMP: + case OP_IMM_REG_CMP: + case OP_COND_BR: + case OP_STORE16: + case OP_STORE32: + case OP_BIT: + case OP_EX2: + trace_result (0, 0); + break; + + case OP_LOAD16: + case OP_STSR: + trace_result (1, State.regs[OP[0]]); + break; + + case OP_REG_REG: + case OP_REG_REG_MOVE: + case OP_IMM_REG: + case OP_IMM_REG_MOVE: + case OP_LOAD32: + case OP_EX1: + trace_result (1, State.regs[OP[1]]); + break; + + case OP_IMM_REG_REG: + case OP_UIMM_REG_REG: + case OP_IMM16_REG_REG: + case OP_UIMM16_REG_REG: + trace_result (1, State.regs[OP[1]]); + break; + + case OP_JUMP: + if (OP[1] != 0) + trace_result (1, State.regs[OP[1]]); + else + trace_result (0, 0); + break; + + case OP_LDSR: + trace_result (1, State.sregs[OP[1]]); + break; + } +} +#endif + + +/* Returns 1 if the specific condition is met, returns 0 otherwise. */ +int +condition_met (unsigned code) +{ + unsigned int psw = PSW; + + switch (code & 0xf) + { + case 0x0: return ((psw & PSW_OV) != 0); + case 0x1: return ((psw & PSW_CY) != 0); + case 0x2: return ((psw & PSW_Z) != 0); + case 0x3: return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) != 0); + case 0x4: return ((psw & PSW_S) != 0); + /*case 0x5: return 1;*/ + case 0x6: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) != 0); + case 0x7: return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) != 0); + case 0x8: return ((psw & PSW_OV) == 0); + case 0x9: return ((psw & PSW_CY) == 0); + case 0xa: return ((psw & PSW_Z) == 0); + case 0xb: return ((((psw & PSW_CY) != 0) | ((psw & PSW_Z) != 0)) == 0); + case 0xc: return ((psw & PSW_S) == 0); + case 0xd: return ((psw & PSW_SAT) != 0); + case 0xe: return ((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) == 0); + case 0xf: return (((((psw & PSW_S) != 0) ^ ((psw & PSW_OV) != 0)) || ((psw & PSW_Z) != 0)) == 0); + } + + return 1; +} + +static unsigned long +Add32 (unsigned long a1, unsigned long a2, int * carry) +{ + unsigned long result = (a1 + a2); + + * carry = (result < a1); + + return result; +} + +static void +Multiply64 (int sign, unsigned long op0) +{ + unsigned long op1; + unsigned long lo; + unsigned long mid1; + unsigned long mid2; + unsigned long hi; + unsigned long RdLo; + unsigned long RdHi; + int carry; + + op1 = State.regs[ OP[1] ]; + + if (sign) + { + /* Compute sign of result and adjust operands if necessary. */ + + sign = (op0 ^ op1) & 0x80000000; + + if (((signed long) op0) < 0) + op0 = - op0; + + if (((signed long) op1) < 0) + op1 = - op1; + } + + /* We can split the 32x32 into four 16x16 operations. This ensures + that we do not lose precision on 32bit only hosts: */ + lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF)); + mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); + mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF)); + hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); + + /* We now need to add all of these results together, taking care + to propogate the carries from the additions: */ + RdLo = Add32 (lo, (mid1 << 16), & carry); + RdHi = carry; + RdLo = Add32 (RdLo, (mid2 << 16), & carry); + RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); + + if (sign) + { + /* Negate result if necessary. */ + + RdLo = ~ RdLo; + RdHi = ~ RdHi; + if (RdLo == 0xFFFFFFFF) + { + RdLo = 0; + RdHi += 1; + } + else + RdLo += 1; + } + + /* Don't store into register 0. */ + if (OP[1]) + State.regs[ OP[1] ] = RdLo; + if (OP[2] >> 11) + State.regs[ OP[2] >> 11 ] = RdHi; + + return; +} + + +/* Read a null terminated string from memory, return in a buffer */ +static char * +fetch_str (sd, addr) + SIM_DESC sd; + address_word addr; +{ + char *buf; + int nr = 0; + while (sim_core_read_1 (STATE_CPU (sd, 0), + PC, read_map, addr + nr) != 0) + nr++; + buf = NZALLOC (char, nr + 1); + sim_read (simulator, addr, buf, nr); + return buf; +} + +/* Read a null terminated argument vector from memory, return in a + buffer */ +static char ** +fetch_argv (sd, addr) + SIM_DESC sd; + address_word addr; +{ + int max_nr = 64; + int nr = 0; + char **buf = xmalloc (max_nr * sizeof (char*)); + while (1) + { + unsigned32 a = sim_core_read_4 (STATE_CPU (sd, 0), + PC, read_map, addr + nr * 4); + if (a == 0) break; + buf[nr] = fetch_str (sd, a); + nr ++; + if (nr == max_nr - 1) + { + max_nr += 50; + buf = xrealloc (buf, max_nr * sizeof (char*)); + } + } + buf[nr] = 0; + return buf; +} + + +/* sst.b */ +int +OP_380 () +{ + trace_input ("sst.b", OP_STORE16, 1); + + store_mem (State.regs[30] + (OP[3] & 0x7f), 1, State.regs[ OP[1] ]); + + trace_output (OP_STORE16); + + return 2; +} + +/* sst.h */ +int +OP_480 () +{ + trace_input ("sst.h", OP_STORE16, 2); + + store_mem (State.regs[30] + ((OP[3] & 0x7f) << 1), 2, State.regs[ OP[1] ]); + + trace_output (OP_STORE16); + + return 2; +} + +/* sst.w */ +int +OP_501 () +{ + trace_input ("sst.w", OP_STORE16, 4); + + store_mem (State.regs[30] + ((OP[3] & 0x7e) << 1), 4, State.regs[ OP[1] ]); + + trace_output (OP_STORE16); + + return 2; +} + +/* ld.b */ +int +OP_700 () +{ + int adr; + + trace_input ("ld.b", OP_LOAD32, 1); + + adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]); + + State.regs[ OP[1] ] = EXTEND8 (load_mem (adr, 1)); + + trace_output (OP_LOAD32); + + return 4; +} + +/* ld.h */ +int +OP_720 () +{ + int adr; + + trace_input ("ld.h", OP_LOAD32, 2); + + adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]); + adr &= ~0x1; + + State.regs[ OP[1] ] = EXTEND16 (load_mem (adr, 2)); + + trace_output (OP_LOAD32); + + return 4; +} + +/* ld.w */ +int +OP_10720 () +{ + int adr; + + trace_input ("ld.w", OP_LOAD32, 4); + + adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1); + adr &= ~0x3; + + State.regs[ OP[1] ] = load_mem (adr, 4); + + trace_output (OP_LOAD32); + + return 4; +} + +/* st.b */ +int +OP_740 () +{ + trace_input ("st.b", OP_STORE32, 1); + + store_mem (State.regs[ OP[0] ] + EXTEND16 (OP[2]), 1, State.regs[ OP[1] ]); + + trace_output (OP_STORE32); + + return 4; +} + +/* st.h */ +int +OP_760 () +{ + int adr; + + trace_input ("st.h", OP_STORE32, 2); + + adr = State.regs[ OP[0] ] + EXTEND16 (OP[2]); + adr &= ~1; + + store_mem (adr, 2, State.regs[ OP[1] ]); + + trace_output (OP_STORE32); + + return 4; +} + +/* st.w */ +int +OP_10760 () +{ + int adr; + + trace_input ("st.w", OP_STORE32, 4); + + adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1); + adr &= ~3; + + store_mem (adr, 4, State.regs[ OP[1] ]); + + trace_output (OP_STORE32); + + return 4; +} + +/* add reg, reg */ +int +OP_1C0 () +{ + unsigned int op0, op1, result, z, s, cy, ov; + + trace_input ("add", OP_REG_REG, 0); + + /* Compute the result. */ + + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + + result = op0 + op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG); + + return 2; +} + +/* add sign_extend(imm5), reg */ +int +OP_240 () +{ + unsigned int op0, op1, result, z, s, cy, ov; + int temp; + + trace_input ("add", OP_IMM_REG, 0); + + /* Compute the result. */ + temp = SEXT5 (OP[0]); + op0 = temp; + op1 = State.regs[OP[1]]; + result = op0 + op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_IMM_REG); + + return 2; +} + +/* addi sign_extend(imm16), reg, reg */ +int +OP_600 () +{ + unsigned int op0, op1, result, z, s, cy, ov; + + trace_input ("addi", OP_IMM16_REG_REG, 0); + + /* Compute the result. */ + + op0 = EXTEND16 (OP[2]); + op1 = State.regs[ OP[0] ]; + result = op0 + op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_IMM16_REG_REG); + + return 4; +} + +/* sub reg1, reg2 */ +int +OP_1A0 () +{ + unsigned int op0, op1, result, z, s, cy, ov; + + trace_input ("sub", OP_REG_REG, 0); + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op1 - op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (op1 < op0); + ov = ((op1 & 0x80000000) != (op0 & 0x80000000) + && (op1 & 0x80000000) != (result & 0x80000000)); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG); + + return 2; +} + +/* subr reg1, reg2 */ +int +OP_180 () +{ + unsigned int op0, op1, result, z, s, cy, ov; + + trace_input ("subr", OP_REG_REG, 0); + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op0 - op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (op0 < op1); + ov = ((op0 & 0x80000000) != (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG); + + return 2; +} + +/* sxh reg1 */ +int +OP_E0 () +{ + trace_input ("mulh", OP_REG_REG, 0); + + State.regs[ OP[1] ] = (EXTEND16 (State.regs[ OP[1] ]) * EXTEND16 (State.regs[ OP[0] ])); + + trace_output (OP_REG_REG); + + return 2; +} + +/* mulh sign_extend(imm5), reg2 */ +int +OP_2E0 () +{ + trace_input ("mulh", OP_IMM_REG, 0); + + State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[1] ]) * SEXT5 (OP[0]); + + trace_output (OP_IMM_REG); + + return 2; +} + +/* mulhi imm16, reg1, reg2 */ +int +OP_6E0 () +{ + trace_input ("mulhi", OP_IMM16_REG_REG, 0); + + State.regs[ OP[1] ] = EXTEND16 (State.regs[ OP[0] ]) * EXTEND16 (OP[2]); + + trace_output (OP_IMM16_REG_REG); + + return 4; +} + +/* cmp reg, reg */ +int +OP_1E0 () +{ + unsigned int op0, op1, result, z, s, cy, ov; + + trace_input ("cmp", OP_REG_REG_CMP, 0); + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op1 - op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (op1 < op0); + ov = ((op1 & 0x80000000) != (op0 & 0x80000000) + && (op1 & 0x80000000) != (result & 0x80000000)); + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_REG_REG_CMP); + + return 2; +} + +/* cmp sign_extend(imm5), reg */ +int +OP_260 () +{ + unsigned int op0, op1, result, z, s, cy, ov; + int temp; + + /* Compute the result. */ + trace_input ("cmp", OP_IMM_REG_CMP, 0); + temp = SEXT5 (OP[0]); + op0 = temp; + op1 = State.regs[OP[1]]; + result = op1 - op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (op1 < op0); + ov = ((op1 & 0x80000000) != (op0 & 0x80000000) + && (op1 & 0x80000000) != (result & 0x80000000)); + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + trace_output (OP_IMM_REG_CMP); + + return 2; +} + +/* setf cccc,reg2 */ +int +OP_7E0 () +{ + trace_input ("setf", OP_EX1, 0); + + State.regs[ OP[1] ] = condition_met (OP[0]); + + trace_output (OP_EX1); + + return 4; +} + +/* satadd reg,reg */ +int +OP_C0 () +{ + unsigned int op0, op1, result, z, s, cy, ov, sat; + + trace_input ("satadd", OP_REG_REG, 0); + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op0 + op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + sat = ov; + + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) + | (sat ? PSW_SAT : 0)); + + trace_output (OP_REG_REG); + + return 2; +} + +/* satadd sign_extend(imm5), reg */ +int +OP_220 () +{ + unsigned int op0, op1, result, z, s, cy, ov, sat; + + int temp; + + trace_input ("satadd", OP_IMM_REG, 0); + + /* Compute the result. */ + temp = SEXT5 (OP[0]); + op0 = temp; + op1 = State.regs[OP[1]]; + result = op0 + op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (result < op0 || result < op1); + ov = ((op0 & 0x80000000) == (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + sat = ov; + + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) + | (sat ? PSW_SAT : 0)); + trace_output (OP_IMM_REG); + + return 2; +} + +/* satsub reg1, reg2 */ +int +OP_A0 () +{ + unsigned int op0, op1, result, z, s, cy, ov, sat; + + trace_input ("satsub", OP_REG_REG, 0); + + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op1 - op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (op1 < op0); + ov = ((op1 & 0x80000000) != (op0 & 0x80000000) + && (op1 & 0x80000000) != (result & 0x80000000)); + sat = ov; + + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) + | (sat ? PSW_SAT : 0)); + + trace_output (OP_REG_REG); + return 2; +} + +/* satsubi sign_extend(imm16), reg */ +int +OP_660 () +{ + unsigned int op0, op1, result, z, s, cy, ov, sat; + int temp; + + trace_input ("satsubi", OP_IMM_REG, 0); + + /* Compute the result. */ + temp = EXTEND16 (OP[2]); + op0 = temp; + op1 = State.regs[ OP[0] ]; + result = op1 - op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (op1 < op0); + ov = ((op1 & 0x80000000) != (op0 & 0x80000000) + && (op1 & 0x80000000) != (result & 0x80000000)); + sat = ov; + + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) + | (sat ? PSW_SAT : 0)); + + trace_output (OP_IMM_REG); + + return 4; +} + +/* satsubr reg,reg */ +int +OP_80 () +{ + unsigned int op0, op1, result, z, s, cy, ov, sat; + + trace_input ("satsubr", OP_REG_REG, 0); + + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op0 - op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = (op0 < op1); + ov = ((op0 & 0x80000000) != (op1 & 0x80000000) + && (op0 & 0x80000000) != (result & 0x80000000)); + sat = ov; + + /* Handle saturated results. */ + if (sat && s) + { + /* An overflow that results in a negative result implies that we + became too positive. */ + result = 0x7fffffff; + s = 0; + } + else if (sat) + { + /* Any other overflow must have thus been too negative. */ + result = 0x80000000; + s = 1; + z = 0; + } + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0) + | (sat ? PSW_SAT : 0)); + + trace_output (OP_REG_REG); + + return 2; +} + +/* tst reg,reg */ +int +OP_160 () +{ + unsigned int op0, op1, result, z, s; + + trace_input ("tst", OP_REG_REG_CMP, 0); + + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op0 & op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG_CMP); + + return 2; +} + +/* mov sign_extend(imm5), reg */ +int +OP_200 () +{ + int value = SEXT5 (OP[0]); + + trace_input ("mov", OP_IMM_REG_MOVE, 0); + + State.regs[ OP[1] ] = value; + + trace_output (OP_IMM_REG_MOVE); + + return 2; +} + +/* movhi imm16, reg, reg */ +int +OP_640 () +{ + trace_input ("movhi", OP_UIMM16_REG_REG, 16); + + State.regs[ OP[1] ] = State.regs[ OP[0] ] + (OP[2] << 16); + + trace_output (OP_UIMM16_REG_REG); + + return 4; +} + +/* sar zero_extend(imm5),reg1 */ +int +OP_2A0 () +{ + unsigned int op0, op1, result, z, s, cy; + + trace_input ("sar", OP_IMM_REG, 0); + op0 = OP[0]; + op1 = State.regs[ OP[1] ]; + result = (signed)op1 >> op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; + + /* Store the result and condition codes. */ + State.regs[ OP[1] ] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0)); + trace_output (OP_IMM_REG); + + return 2; +} + +/* sar reg1, reg2 */ +int +OP_A007E0 () +{ + unsigned int op0, op1, result, z, s, cy; + + trace_input ("sar", OP_REG_REG, 0); + + op0 = State.regs[ OP[0] ] & 0x1f; + op1 = State.regs[ OP[1] ]; + result = (signed)op1 >> op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0)); + trace_output (OP_REG_REG); + + return 4; +} + +/* shl zero_extend(imm5),reg1 */ +int +OP_2C0 () +{ + unsigned int op0, op1, result, z, s, cy; + + trace_input ("shl", OP_IMM_REG, 0); + op0 = OP[0]; + op1 = State.regs[ OP[1] ]; + result = op1 << op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = op0 ? (op1 & (1 << (32 - op0))) : 0; + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0)); + trace_output (OP_IMM_REG); + + return 2; +} + +/* shl reg1, reg2 */ +int +OP_C007E0 () +{ + unsigned int op0, op1, result, z, s, cy; + + trace_input ("shl", OP_REG_REG, 0); + op0 = State.regs[ OP[0] ] & 0x1f; + op1 = State.regs[ OP[1] ]; + result = op1 << op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = op0 ? (op1 & (1 << (32 - op0))) : 0; + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0)); + trace_output (OP_REG_REG); + + return 4; +} + +/* shr zero_extend(imm5),reg1 */ +int +OP_280 () +{ + unsigned int op0, op1, result, z, s, cy; + + trace_input ("shr", OP_IMM_REG, 0); + op0 = OP[0]; + op1 = State.regs[ OP[1] ]; + result = op1 >> op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0)); + trace_output (OP_IMM_REG); + + return 2; +} + +/* shr reg1, reg2 */ +int +OP_8007E0 () +{ + unsigned int op0, op1, result, z, s, cy; + + trace_input ("shr", OP_REG_REG, 0); + op0 = State.regs[ OP[0] ] & 0x1f; + op1 = State.regs[ OP[1] ]; + result = op1 >> op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + cy = op0 ? (op1 & (1 << (op0 - 1))) : 0; + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV | PSW_CY); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0)); + trace_output (OP_REG_REG); + + return 4; +} + +/* or reg, reg */ +int +OP_100 () +{ + unsigned int op0, op1, result, z, s; + + trace_input ("or", OP_REG_REG, 0); + + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op0 | op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG); + + return 2; +} + +/* ori zero_extend(imm16), reg, reg */ +int +OP_680 () +{ + unsigned int op0, op1, result, z, s; + + trace_input ("ori", OP_UIMM16_REG_REG, 0); + op0 = OP[2]; + op1 = State.regs[ OP[0] ]; + result = op0 | op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_UIMM16_REG_REG); + + return 4; +} + +/* and reg, reg */ +int +OP_140 () +{ + unsigned int op0, op1, result, z, s; + + trace_input ("and", OP_REG_REG, 0); + + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op0 & op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG); + + return 2; +} + +/* andi zero_extend(imm16), reg, reg */ +int +OP_6C0 () +{ + unsigned int result, z; + + trace_input ("andi", OP_UIMM16_REG_REG, 0); + + result = OP[2] & State.regs[ OP[0] ]; + + /* Compute the condition codes. */ + z = (result == 0); + + /* Store the result and condition codes. */ + State.regs[ OP[1] ] = result; + + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= (z ? PSW_Z : 0); + + trace_output (OP_UIMM16_REG_REG); + + return 4; +} + +/* xor reg, reg */ +int +OP_120 () +{ + unsigned int op0, op1, result, z, s; + + trace_input ("xor", OP_REG_REG, 0); + + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + op1 = State.regs[ OP[1] ]; + result = op0 ^ op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG); + + return 2; +} + +/* xori zero_extend(imm16), reg, reg */ +int +OP_6A0 () +{ + unsigned int op0, op1, result, z, s; + + trace_input ("xori", OP_UIMM16_REG_REG, 0); + op0 = OP[2]; + op1 = State.regs[ OP[0] ]; + result = op0 ^ op1; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_UIMM16_REG_REG); + + return 4; +} + +/* not reg1, reg2 */ +int +OP_20 () +{ + unsigned int op0, result, z, s; + + trace_input ("not", OP_REG_REG_MOVE, 0); + /* Compute the result. */ + op0 = State.regs[ OP[0] ]; + result = ~op0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0)); + trace_output (OP_REG_REG_MOVE); + + return 2; +} + +/* set1 */ +int +OP_7C0 () +{ + unsigned int op0, op1, op2; + int temp; + + trace_input ("set1", OP_BIT, 0); + op0 = State.regs[ OP[0] ]; + op1 = OP[1] & 0x7; + temp = EXTEND16 (OP[2]); + op2 = temp; + temp = load_mem (op0 + op2, 1); + PSW &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + PSW |= PSW_Z; + temp |= (1 << op1); + store_mem (op0 + op2, 1, temp); + trace_output (OP_BIT); + + return 4; +} + +/* not1 */ +int +OP_47C0 () +{ + unsigned int op0, op1, op2; + int temp; + + trace_input ("not1", OP_BIT, 0); + op0 = State.regs[ OP[0] ]; + op1 = OP[1] & 0x7; + temp = EXTEND16 (OP[2]); + op2 = temp; + temp = load_mem (op0 + op2, 1); + PSW &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + PSW |= PSW_Z; + temp ^= (1 << op1); + store_mem (op0 + op2, 1, temp); + trace_output (OP_BIT); + + return 4; +} + +/* clr1 */ +int +OP_87C0 () +{ + unsigned int op0, op1, op2; + int temp; + + trace_input ("clr1", OP_BIT, 0); + op0 = State.regs[ OP[0] ]; + op1 = OP[1] & 0x7; + temp = EXTEND16 (OP[2]); + op2 = temp; + temp = load_mem (op0 + op2, 1); + PSW &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + PSW |= PSW_Z; + temp &= ~(1 << op1); + store_mem (op0 + op2, 1, temp); + trace_output (OP_BIT); + + return 4; +} + +/* tst1 */ +int +OP_C7C0 () +{ + unsigned int op0, op1, op2; + int temp; + + trace_input ("tst1", OP_BIT, 0); + op0 = State.regs[ OP[0] ]; + op1 = OP[1] & 0x7; + temp = EXTEND16 (OP[2]); + op2 = temp; + temp = load_mem (op0 + op2, 1); + PSW &= ~PSW_Z; + if ((temp & (1 << op1)) == 0) + PSW |= PSW_Z; + trace_output (OP_BIT); + + return 4; +} + +/* di */ +int +OP_16007E0 () +{ + trace_input ("di", OP_NONE, 0); + PSW |= PSW_ID; + trace_output (OP_NONE); + + return 4; +} + +/* ei */ +int +OP_16087E0 () +{ + trace_input ("ei", OP_NONE, 0); + PSW &= ~PSW_ID; + trace_output (OP_NONE); + + return 4; +} + +/* halt */ +int +OP_12007E0 () +{ + trace_input ("halt", OP_NONE, 0); + /* FIXME this should put processor into a mode where NMI still handled */ + trace_output (OP_NONE); + sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, + sim_stopped, SIM_SIGTRAP); + return 0; +} + +/* trap */ +int +OP_10007E0 () +{ + trace_input ("trap", OP_TRAP, 0); + trace_output (OP_TRAP); + + /* Trap 31 is used for simulating OS I/O functions */ + + if (OP[0] == 31) + { + int save_errno = errno; + errno = 0; + +/* Registers passed to trap 0 */ + +#define FUNC State.regs[6] /* function number, return value */ +#define PARM1 State.regs[7] /* optional parm 1 */ +#define PARM2 State.regs[8] /* optional parm 2 */ +#define PARM3 State.regs[9] /* optional parm 3 */ + +/* Registers set by trap 0 */ + +#define RETVAL State.regs[10] /* return value */ +#define RETERR State.regs[11] /* return error code */ + +/* Turn a pointer in a register into a pointer into real memory. */ + +#define MEMPTR(x) (map (x)) + + switch (FUNC) + { + +#ifdef HAVE_FORK +#ifdef TARGET_SYS_fork + case TARGET_SYS_fork: + RETVAL = fork (); + break; +#endif +#endif + +#ifdef HAVE_EXECVE +#ifdef TARGET_SYS_execv + case TARGET_SYS_execve: + { + char *path = fetch_str (simulator, PARM1); + char **argv = fetch_argv (simulator, PARM2); + char **envp = fetch_argv (simulator, PARM3); + RETVAL = execve (path, argv, envp); + zfree (path); + freeargv (argv); + freeargv (envp); + break; + } +#endif +#endif + +#if HAVE_EXECV +#ifdef TARGET_SYS_execv + case TARGET_SYS_execv: + { + char *path = fetch_str (simulator, PARM1); + char **argv = fetch_argv (simulator, PARM2); + RETVAL = execv (path, argv); + zfree (path); + freeargv (argv); + break; + } +#endif +#endif + +#if 0 +#ifdef TARGET_SYS_pipe + case TARGET_SYS_pipe: + { + reg_t buf; + int host_fd[2]; + + buf = PARM1; + RETVAL = pipe (host_fd); + SW (buf, host_fd[0]); + buf += sizeof(uint16); + SW (buf, host_fd[1]); + } + break; +#endif +#endif + +#if 0 +#ifdef TARGET_SYS_wait + case TARGET_SYS_wait: + { + int status; + + RETVAL = wait (&status); + SW (PARM1, status); + } + break; +#endif +#endif + +#ifdef TARGET_SYS_read + case TARGET_SYS_read: + { + char *buf = zalloc (PARM3); + RETVAL = sim_io_read (simulator, PARM1, buf, PARM3); + sim_write (simulator, PARM2, buf, PARM3); + zfree (buf); + break; + } +#endif + +#ifdef TARGET_SYS_write + case TARGET_SYS_write: + { + char *buf = zalloc (PARM3); + sim_read (simulator, PARM2, buf, PARM3); + if (PARM1 == 1) + RETVAL = sim_io_write_stdout (simulator, buf, PARM3); + else + RETVAL = sim_io_write (simulator, PARM1, buf, PARM3); + zfree (buf); + break; + } +#endif + +#ifdef TARGET_SYS_lseek + case TARGET_SYS_lseek: + RETVAL = sim_io_lseek (simulator, PARM1, PARM2, PARM3); + break; +#endif + +#ifdef TARGET_SYS_close + case TARGET_SYS_close: + RETVAL = sim_io_close (simulator, PARM1); + break; +#endif + +#ifdef TARGET_SYS_open + case TARGET_SYS_open: + { + char *buf = fetch_str (simulator, PARM1); + RETVAL = sim_io_open (simulator, buf, PARM2); + zfree (buf); + break; + } +#endif + +#ifdef TARGET_SYS_exit + case TARGET_SYS_exit: + if ((PARM1 & 0xffff0000) == 0xdead0000 && (PARM1 & 0xffff) != 0) + /* get signal encoded by kill */ + sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, + sim_signalled, PARM1 & 0xffff); + else if (PARM1 == 0xdead) + /* old libraries */ + sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, + sim_stopped, SIM_SIGABRT); + else + /* PARM1 has exit status */ + sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, + sim_exited, PARM1); + break; +#endif + +#if !defined(__GO32__) && !defined(_WIN32) +#ifdef TARGET_SYS_stat + case TARGET_SYS_stat: /* added at hmsi */ + /* stat system call */ + { + struct stat host_stat; + reg_t buf; + char *path = fetch_str (simulator, PARM1); + + RETVAL = stat (path, &host_stat); + + zfree (path); + buf = PARM2; + + /* Just wild-assed guesses. */ + store_mem (buf, 2, host_stat.st_dev); + store_mem (buf + 2, 2, host_stat.st_ino); + store_mem (buf + 4, 4, host_stat.st_mode); + store_mem (buf + 8, 2, host_stat.st_nlink); + store_mem (buf + 10, 2, host_stat.st_uid); + store_mem (buf + 12, 2, host_stat.st_gid); + store_mem (buf + 14, 2, host_stat.st_rdev); + store_mem (buf + 16, 4, host_stat.st_size); + store_mem (buf + 20, 4, host_stat.st_atime); + store_mem (buf + 28, 4, host_stat.st_mtime); + store_mem (buf + 36, 4, host_stat.st_ctime); + } + break; +#endif +#endif + +#ifdef HAVE_CHOWN +#ifdef TARGET_SYS_chown + case TARGET_SYS_chown: + { + char *path = fetch_str (simulator, PARM1); + RETVAL = chown (path, PARM2, PARM3); + zfree (path); + } + break; +#endif +#endif + +#if HAVE_CHMOD +#ifdef TARGET_SYS_chmod + case TARGET_SYS_chmod: + { + char *path = fetch_str (simulator, PARM1); + RETVAL = chmod (path, PARM2); + zfree (path); + } + break; +#endif +#endif + +#ifdef TARGET_SYS_time +#if HAVE_TIME + case TARGET_SYS_time: + { + time_t now; + RETVAL = time (&now); + store_mem (PARM1, 4, now); + } + break; +#endif +#endif + +#if !defined(__GO32__) && !defined(_WIN32) +#ifdef TARGET_SYS_times + case TARGET_SYS_times: + { + struct tms tms; + RETVAL = times (&tms); + store_mem (PARM1, 4, tms.tms_utime); + store_mem (PARM1 + 4, 4, tms.tms_stime); + store_mem (PARM1 + 8, 4, tms.tms_cutime); + store_mem (PARM1 + 12, 4, tms.tms_cstime); + break; + } +#endif +#endif + +#ifdef TARGET_SYS_gettimeofday +#if !defined(__GO32__) && !defined(_WIN32) + case TARGET_SYS_gettimeofday: + { + struct timeval t; + struct timezone tz; + RETVAL = gettimeofday (&t, &tz); + store_mem (PARM1, 4, t.tv_sec); + store_mem (PARM1 + 4, 4, t.tv_usec); + store_mem (PARM2, 4, tz.tz_minuteswest); + store_mem (PARM2 + 4, 4, tz.tz_dsttime); + break; + } +#endif +#endif + +#ifdef TARGET_SYS_utime +#if HAVE_UTIME + case TARGET_SYS_utime: + { + /* Cast the second argument to void *, to avoid type mismatch + if a prototype is present. */ + sim_io_error (simulator, "Utime not supported"); + /* RETVAL = utime (path, (void *) MEMPTR (PARM2)); */ + } + break; +#endif +#endif + + default: + abort (); + } + RETERR = errno; + errno = save_errno; + + return 4; + } + else + { /* Trap 0 -> 30 */ + EIPC = PC + 4; + EIPSW = PSW; + /* Mask out EICC */ + ECR &= 0xffff0000; + ECR |= 0x40 + OP[0]; + /* Flag that we are now doing exception processing. */ + PSW |= PSW_EP | PSW_ID; + PC = (OP[0] < 0x10) ? 0x40 : 0x50; + + return 0; + } +} + +/* tst1 reg2, [reg1] */ +int +OP_E607E0 (void) +{ + int temp; + + trace_input ("tst1", OP_BIT, 1); + + temp = load_mem (State.regs[ OP[0] ], 1); + + PSW &= ~PSW_Z; + if ((temp & (1 << (State.regs[ OP[1] ] & 0x7))) == 0) + PSW |= PSW_Z; + + trace_output (OP_BIT); + + return 4; +} + +/* mulu reg1, reg2, reg3 */ +int +OP_22207E0 (void) +{ + trace_input ("mulu", OP_REG_REG_REG, 0); + + Multiply64 (0, State.regs[ OP[0] ]); + + trace_output (OP_REG_REG_REG); + + return 4; +} + +#define BIT_CHANGE_OP( name, binop ) \ + unsigned int bit; \ + unsigned int temp; \ + \ + trace_input (name, OP_BIT_CHANGE, 0); \ + \ + bit = 1 << (State.regs[ OP[1] ] & 0x7); \ + temp = load_mem (State.regs[ OP[0] ], 1); \ + \ + PSW &= ~PSW_Z; \ + if ((temp & bit) == 0) \ + PSW |= PSW_Z; \ + temp binop bit; \ + \ + store_mem (State.regs[ OP[0] ], 1, temp); \ + \ + trace_output (OP_BIT_CHANGE); \ + \ + return 4; + +/* clr1 reg2, [reg1] */ +int +OP_E407E0 (void) +{ + BIT_CHANGE_OP ("clr1", &= ~ ); +} + +/* not1 reg2, [reg1] */ +int +OP_E207E0 (void) +{ + BIT_CHANGE_OP ("not1", ^= ); +} + +/* set1 */ +int +OP_E007E0 (void) +{ + BIT_CHANGE_OP ("set1", |= ); +} + +/* sasf */ +int +OP_20007E0 (void) +{ + trace_input ("sasf", OP_EX1, 0); + + State.regs[ OP[1] ] = (State.regs[ OP[1] ] << 1) | condition_met (OP[0]); + + trace_output (OP_EX1); + + return 4; +} + +/* This function is courtesy of Sugimoto at NEC, via Seow Tan + (Soew_Tan@el.nec.com) */ +void +divun +( + unsigned int N, + unsigned long int als, + unsigned long int sfi, + unsigned32 /*unsigned long int*/ * quotient_ptr, + unsigned32 /*unsigned long int*/ * remainder_ptr, + int * overflow_ptr +) +{ + unsigned long ald = sfi >> (N - 1); + unsigned long alo = als; + unsigned int Q = 1; + unsigned int C; + unsigned int S = 0; + unsigned int i; + unsigned int R1 = 1; + unsigned int DBZ = (als == 0) ? 1 : 0; + unsigned long alt = Q ? ~als : als; + + /* 1st Loop */ + alo = ald + alt + Q; + C = (((alt >> 31) & (ald >> 31)) + | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); + C = C ^ Q; + Q = ~(C ^ S) & 1; + R1 = (alo == 0) ? 0 : (R1 & Q); + if ((S ^ (alo>>31)) && !C) + { + DBZ = 1; + } + S = alo >> 31; + sfi = (sfi << (32-N+1)) | Q; + ald = (alo << 1) | (sfi >> 31); + + /* 2nd - N-1th Loop */ + for (i = 2; i < N; i++) + { + alt = Q ? ~als : als; + alo = ald + alt + Q; + C = (((alt >> 31) & (ald >> 31)) + | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); + C = C ^ Q; + Q = ~(C ^ S) & 1; + R1 = (alo == 0) ? 0 : (R1 & Q); + if ((S ^ (alo>>31)) && !C && !DBZ) + { + DBZ = 1; + } + S = alo >> 31; + sfi = (sfi << 1) | Q; + ald = (alo << 1) | (sfi >> 31); + } + + /* Nth Loop */ + alt = Q ? ~als : als; + alo = ald + alt + Q; + C = (((alt >> 31) & (ald >> 31)) + | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); + C = C ^ Q; + Q = ~(C ^ S) & 1; + R1 = (alo == 0) ? 0 : (R1 & Q); + if ((S ^ (alo>>31)) && !C) + { + DBZ = 1; + } + + * quotient_ptr = (sfi << 1) | Q; + * remainder_ptr = Q ? alo : (alo + als); + * overflow_ptr = DBZ | R1; +} + +/* This function is courtesy of Sugimoto at NEC, via Seow Tan (Soew_Tan@el.nec.com) */ +void +divn +( + unsigned int N, + unsigned long int als, + unsigned long int sfi, + signed32 /*signed long int*/ * quotient_ptr, + signed32 /*signed long int*/ * remainder_ptr, + int * overflow_ptr +) +{ + unsigned long ald = (signed long) sfi >> (N - 1); + unsigned long alo = als; + unsigned int SS = als >> 31; + unsigned int SD = sfi >> 31; + unsigned int R1 = 1; + unsigned int OV; + unsigned int DBZ = als == 0 ? 1 : 0; + unsigned int Q = ~(SS ^ SD) & 1; + unsigned int C; + unsigned int S; + unsigned int i; + unsigned long alt = Q ? ~als : als; + + + /* 1st Loop */ + + alo = ald + alt + Q; + C = (((alt >> 31) & (ald >> 31)) + | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); + Q = C ^ SS; + R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); + S = alo >> 31; + sfi = (sfi << (32-N+1)) | Q; + ald = (alo << 1) | (sfi >> 31); + if ((alo >> 31) ^ (ald >> 31)) + { + DBZ = 1; + } + + /* 2nd - N-1th Loop */ + + for (i = 2; i < N; i++) + { + alt = Q ? ~als : als; + alo = ald + alt + Q; + C = (((alt >> 31) & (ald >> 31)) + | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); + Q = C ^ SS; + R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); + S = alo >> 31; + sfi = (sfi << 1) | Q; + ald = (alo << 1) | (sfi >> 31); + if ((alo >> 31) ^ (ald >> 31)) + { + DBZ = 1; + } + } + + /* Nth Loop */ + alt = Q ? ~als : als; + alo = ald + alt + Q; + C = (((alt >> 31) & (ald >> 31)) + | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); + Q = C ^ SS; + R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); + sfi = (sfi << (32-N+1)); + ald = alo; + + /* End */ + if (alo != 0) + { + alt = Q ? ~als : als; + alo = ald + alt + Q; + } + R1 = R1 & ((~alo >> 31) ^ SD); + if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald; + if (N != 32) + ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q; + else + ald = sfi = sfi | Q; + + OV = DBZ | ((alo == 0) ? 0 : R1); + + * remainder_ptr = alo; + + /* Adj */ + if (((alo != 0) && ((SS ^ SD) ^ R1)) + || ((alo == 0) && (SS ^ R1))) + alo = ald + 1; + else + alo = ald; + + OV = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31)); + + * quotient_ptr = alo; + * overflow_ptr = OV; +} + +/* sdivun imm5, reg1, reg2, reg3 */ +int +OP_1C207E0 (void) +{ + unsigned32 /*unsigned long int*/ quotient; + unsigned32 /*unsigned long int*/ remainder; + unsigned long int divide_by; + unsigned long int divide_this; + int overflow = 0; + unsigned int imm5; + + trace_input ("sdivun", OP_IMM_REG_REG_REG, 0); + + imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); + + divide_by = State.regs[ OP[0] ]; + divide_this = State.regs[ OP[1] ] << imm5; + + divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); + + State.regs[ OP[1] ] = quotient; + State.regs[ OP[2] >> 11 ] = remainder; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient & 0x80000000) PSW |= PSW_S; + + trace_output (OP_IMM_REG_REG_REG); + + return 4; +} + +/* sdivn imm5, reg1, reg2, reg3 */ +int +OP_1C007E0 (void) +{ + signed32 /*signed long int*/ quotient; + signed32 /*signed long int*/ remainder; + signed long int divide_by; + signed long int divide_this; + int overflow = 0; + unsigned int imm5; + + trace_input ("sdivn", OP_IMM_REG_REG_REG, 0); + + imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); + + divide_by = (signed32) State.regs[ OP[0] ]; + divide_this = (signed32) (State.regs[ OP[1] ] << imm5); + + divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); + + State.regs[ OP[1] ] = quotient; + State.regs[ OP[2] >> 11 ] = remainder; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient < 0) PSW |= PSW_S; + + trace_output (OP_IMM_REG_REG_REG); + + return 4; +} + +/* sdivhun imm5, reg1, reg2, reg3 */ +int +OP_18207E0 (void) +{ + unsigned32 /*unsigned long int*/ quotient; + unsigned32 /*unsigned long int*/ remainder; + unsigned long int divide_by; + unsigned long int divide_this; + int overflow = 0; + unsigned int imm5; + + trace_input ("sdivhun", OP_IMM_REG_REG_REG, 0); + + imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); + + divide_by = State.regs[ OP[0] ] & 0xffff; + divide_this = State.regs[ OP[1] ] << imm5; + + divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); + + State.regs[ OP[1] ] = quotient; + State.regs[ OP[2] >> 11 ] = remainder; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient & 0x80000000) PSW |= PSW_S; + + trace_output (OP_IMM_REG_REG_REG); + + return 4; +} + +/* sdivhn imm5, reg1, reg2, reg3 */ +int +OP_18007E0 (void) +{ + signed32 /*signed long int*/ quotient; + signed32 /*signed long int*/ remainder; + signed long int divide_by; + signed long int divide_this; + int overflow = 0; + unsigned int imm5; + + trace_input ("sdivhn", OP_IMM_REG_REG_REG, 0); + + imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); + + divide_by = EXTEND16 (State.regs[ OP[0] ]); + divide_this = (signed32) (State.regs[ OP[1] ] << imm5); + + divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); + + State.regs[ OP[1] ] = quotient; + State.regs[ OP[2] >> 11 ] = remainder; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient < 0) PSW |= PSW_S; + + trace_output (OP_IMM_REG_REG_REG); + + return 4; +} + +/* divu reg1, reg2, reg3 */ +int +OP_2C207E0 (void) +{ + unsigned long int quotient; + unsigned long int remainder; + unsigned long int divide_by; + unsigned long int divide_this; + int overflow = 0; + + trace_input ("divu", OP_REG_REG_REG, 0); + + /* Compute the result. */ + + divide_by = State.regs[ OP[0] ]; + divide_this = State.regs[ OP[1] ]; + + if (divide_by == 0) + { + PSW |= PSW_OV; + } + else + { + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient & 0x80000000) PSW |= PSW_S; + } + + trace_output (OP_REG_REG_REG); + + return 4; +} + +/* div reg1, reg2, reg3 */ +int +OP_2C007E0 (void) +{ + signed long int quotient; + signed long int remainder; + signed long int divide_by; + signed long int divide_this; + + trace_input ("div", OP_REG_REG_REG, 0); + + /* Compute the result. */ + + divide_by = (signed32) State.regs[ OP[0] ]; + divide_this = State.regs[ OP[1] ]; + + if (divide_by == 0) + { + PSW |= PSW_OV; + } + else if (divide_by == -1 && divide_this == (1L << 31)) + { + PSW &= ~PSW_Z; + PSW |= PSW_OV | PSW_S; + State.regs[ OP[1] ] = (1 << 31); + State.regs[ OP[2] >> 11 ] = 0; + } + else + { + divide_this = (signed32) divide_this; + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (quotient == 0) PSW |= PSW_Z; + if (quotient < 0) PSW |= PSW_S; + } + + trace_output (OP_REG_REG_REG); + + return 4; +} + +/* divhu reg1, reg2, reg3 */ +int +OP_28207E0 (void) +{ + unsigned long int quotient; + unsigned long int remainder; + unsigned long int divide_by; + unsigned long int divide_this; + int overflow = 0; + + trace_input ("divhu", OP_REG_REG_REG, 0); + + /* Compute the result. */ + + divide_by = State.regs[ OP[0] ] & 0xffff; + divide_this = State.regs[ OP[1] ]; + + if (divide_by == 0) + { + PSW |= PSW_OV; + } + else + { + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (overflow) PSW |= PSW_OV; + if (quotient == 0) PSW |= PSW_Z; + if (quotient & 0x80000000) PSW |= PSW_S; + } + + trace_output (OP_REG_REG_REG); + + return 4; +} + +/* divh reg1, reg2, reg3 */ +int +OP_28007E0 (void) +{ + signed long int quotient; + signed long int remainder; + signed long int divide_by; + signed long int divide_this; + int overflow = 0; + + trace_input ("divh", OP_REG_REG_REG, 0); + + /* Compute the result. */ + + divide_by = EXTEND16 (State.regs[ OP[0] ]); + divide_this = State.regs[ OP[1] ]; + + if (divide_by == 0) + { + PSW |= PSW_OV; + } + else if (divide_by == -1 && divide_this == (1L << 31)) + { + PSW &= ~PSW_Z; + PSW |= PSW_OV | PSW_S; + State.regs[ OP[1] ] = (1 << 31); + State.regs[ OP[2] >> 11 ] = 0; + } + else + { + divide_this = (signed32) divide_this; + State.regs[ OP[1] ] = quotient = divide_this / divide_by; + State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + + if (quotient == 0) PSW |= PSW_Z; + if (quotient < 0) PSW |= PSW_S; + } + + trace_output (OP_REG_REG_REG); + + return 4; +} + +/* mulu imm9, reg2, reg3 */ +int +OP_24207E0 (void) +{ + trace_input ("mulu", OP_IMM_REG_REG, 0); + + Multiply64 (0, (OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0)); + + trace_output (OP_IMM_REG_REG); + + return 4; +} + +/* mul imm9, reg2, reg3 */ +int +OP_24007E0 (void) +{ + trace_input ("mul", OP_IMM_REG_REG, 0); + + Multiply64 (1, SEXT9 ((OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0))); + + trace_output (OP_IMM_REG_REG); + + return 4; +} + +/* ld.hu */ +int +OP_107E0 (void) +{ + int adr; + + trace_input ("ld.hu", OP_LOAD32, 2); + + adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1); + adr &= ~0x1; + + State.regs[ OP[1] ] = load_mem (adr, 2); + + trace_output (OP_LOAD32); + + return 4; +} + + +/* ld.bu */ +int +OP_10780 (void) +{ + int adr; + + trace_input ("ld.bu", OP_LOAD32, 1); + + adr = (State.regs[ OP[0] ] + + (EXTEND16 (OP[2] & ~1) | ((OP[3] >> 5) & 1))); + + State.regs[ OP[1] ] = load_mem (adr, 1); + + trace_output (OP_LOAD32); + + return 4; +} + +/* prepare list12, imm5, imm32 */ +int +OP_1B0780 (void) +{ + int i; + + trace_input ("prepare", OP_PUSHPOP1, 0); + + /* Store the registers with lower number registers being placed at higher addresses. */ + for (i = 0; i < 12; i++) + if ((OP[3] & (1 << type1_regs[ i ]))) + { + SP -= 4; + store_mem (SP, 4, State.regs[ 20 + i ]); + } + + SP -= (OP[3] & 0x3e) << 1; + + EP = load_mem (PC + 4, 4); + + trace_output (OP_PUSHPOP1); + + return 8; +} + +/* prepare list12, imm5, imm16-32 */ +int +OP_130780 (void) +{ + int i; + + trace_input ("prepare", OP_PUSHPOP1, 0); + + /* Store the registers with lower number registers being placed at higher addresses. */ + for (i = 0; i < 12; i++) + if ((OP[3] & (1 << type1_regs[ i ]))) + { + SP -= 4; + store_mem (SP, 4, State.regs[ 20 + i ]); + } + + SP -= (OP[3] & 0x3e) << 1; + + EP = load_mem (PC + 4, 2) << 16; + + trace_output (OP_PUSHPOP1); + + return 6; +} + +/* prepare list12, imm5, imm16 */ +int +OP_B0780 (void) +{ + int i; + + trace_input ("prepare", OP_PUSHPOP1, 0); + + /* Store the registers with lower number registers being placed at higher addresses. */ + for (i = 0; i < 12; i++) + if ((OP[3] & (1 << type1_regs[ i ]))) + { + SP -= 4; + store_mem (SP, 4, State.regs[ 20 + i ]); + } + + SP -= (OP[3] & 0x3e) << 1; + + EP = EXTEND16 (load_mem (PC + 4, 2)); + + trace_output (OP_PUSHPOP1); + + return 6; +} + +/* prepare list12, imm5, sp */ +int +OP_30780 (void) +{ + int i; + + trace_input ("prepare", OP_PUSHPOP1, 0); + + /* Store the registers with lower number registers being placed at higher addresses. */ + for (i = 0; i < 12; i++) + if ((OP[3] & (1 << type1_regs[ i ]))) + { + SP -= 4; + store_mem (SP, 4, State.regs[ 20 + i ]); + } + + SP -= (OP[3] & 0x3e) << 1; + + EP = SP; + + trace_output (OP_PUSHPOP1); + + return 4; +} + +/* mul reg1, reg2, reg3 */ +int +OP_22007E0 (void) +{ + trace_input ("mul", OP_REG_REG_REG, 0); + + Multiply64 (1, State.regs[ OP[0] ]); + + trace_output (OP_REG_REG_REG); + + return 4; +} + +/* popmh list18 */ +int +OP_307F0 (void) +{ + int i; + + trace_input ("popmh", OP_PUSHPOP2, 0); + + if (OP[3] & (1 << 19)) + { + if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) + { + FEPSW = load_mem ( SP & ~ 3, 4); + FEPC = load_mem ((SP + 4) & ~ 3, 4); + } + else + { + EIPSW = load_mem ( SP & ~ 3, 4); + EIPC = load_mem ((SP + 4) & ~ 3, 4); + } + + SP += 8; + } + + /* Load the registers with lower number registers being retrieved from higher addresses. */ + for (i = 16; i--;) + if ((OP[3] & (1 << type2_regs[ i ]))) + { + State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4); + SP += 4; + } + + trace_output (OP_PUSHPOP2); + + return 4; +} + +/* popml lsit18 */ +int +OP_107F0 (void) +{ + int i; + + trace_input ("popml", OP_PUSHPOP3, 0); + + if (OP[3] & (1 << 19)) + { + if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) + { + FEPSW = load_mem ( SP & ~ 3, 4); + FEPC = load_mem ((SP + 4) & ~ 3, 4); + } + else + { + EIPSW = load_mem ( SP & ~ 3, 4); + EIPC = load_mem ((SP + 4) & ~ 3, 4); + } + + SP += 8; + } + + if (OP[3] & (1 << 3)) + { + PSW = load_mem (SP & ~ 3, 4); + SP += 4; + } + + /* Load the registers with lower number registers being retrieved from higher addresses. */ + for (i = 15; i--;) + if ((OP[3] & (1 << type3_regs[ i ]))) + { + State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4); + SP += 4; + } + + trace_output (OP_PUSHPOP2); + + return 4; +} + +/* pushmh list18 */ +int +OP_307E0 (void) +{ + int i; + + trace_input ("pushmh", OP_PUSHPOP2, 0); + + /* Store the registers with lower number registers being placed at higher addresses. */ + for (i = 0; i < 16; i++) + if ((OP[3] & (1 << type2_regs[ i ]))) + { + SP -= 4; + store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]); + } + + if (OP[3] & (1 << 19)) + { + SP -= 8; + + if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) + { + store_mem ((SP + 4) & ~ 3, 4, FEPC); + store_mem ( SP & ~ 3, 4, FEPSW); + } + else + { + store_mem ((SP + 4) & ~ 3, 4, EIPC); + store_mem ( SP & ~ 3, 4, EIPSW); + } + } + + trace_output (OP_PUSHPOP2); + + return 4; +} +
simops.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property

powered by: WebSVN 2.1.0

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