/* SPIM S20 MIPS simulator. Description of a SPIM S20 instruction. (Layout does not correspond to MIPS machine.) Copyright (C) 1990 by James Larus (larus@cs.wisc.edu). SPIM is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. SPIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to James R. Larus, Computer Sciences Department, University of Wisconsin--Madison, 1210 West Dayton Street, Madison, WI 53706, USA or to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Describes an expression that produce a value for an instruction's immediate field. Immediates have the form: label +/- offset. */ /* $Header: /home/aa/projects/spim/public_html/cvsroot/spimsal/inst.h,v 1.1.1.1 1999/08/21 19:31:25 brg Exp $ */ typedef struct immexpr { long offset; /* Offset from symbol */ struct lab *symbol; /* Symbolic label */ short bits; /* > 0 => 31..16, < 0 => 15..0 */ short pc_relative; /* Non-zero => offset from label in code */ } imm_expr; /* Describes an expression that produce an address for an instruction. Address have the form: label +/- offset (register). */ typedef struct addrexpr { unsigned char reg_no; /* Register number */ imm_expr *imm; /* The immediate part */ } addr_expr; /* Choose bland names for fields and #define the real names below. This is better than a union since it doesn't require an additional level of syntactic indirection in references. */ typedef struct inst_s { short opcode; unsigned char f1; unsigned char f2; unsigned char f3; unsigned char f4; long f5; short f5x; imm_expr *f6; char *comment; } instruction; #define OPCODE(INST) (INST)->opcode #define RS(INST) (INST)->f1 #define FS(INST) (INST)->f1 #define BASE(INST) (INST)->f1 #define RT(INST) (INST)->f2 #define FT(INST) (INST)->f2 #define RD(INST) (INST)->f3 #define FD(INST) (INST)->f3 #define SHAMT(INST) (INST)->f4 #define FORMAT(INST) (INST)->f4 #define IMM(INST) (INST)->f5x #define IOFFSET(INST) (INST)->f5x #define COND(INST) (INST)->f5x #define TARGET(INST) (INST)->f5 #define EXPR(INST) (INST)->f6 #define COMMENT(INST) ((INST)->comment) #define COND_UN 0x1 #define COND_EQ 0x2 #define COND_LT 0x4 #define COND_IN 0x8 /* Raise an exception! */ #define RAISE_EXCEPTION(CAUSE, MISC) \ { \ Cause = (Cause & 0xffffff00) | (((CAUSE) << 2) & 0xff); \ exception_occurred = 1; \ MISC; \ } \ /* Recognized exceptions (see Ch. 5): */ #define INT_EXCPT 0 #define ADDRL_EXCPT 4 #define ADDRS_EXCPT 5 #define IBUS_EXCPT 6 #define DBUS_EXCPT 7 #define SYSCALL_EXCPT 8 #define BKPT_EXCPT 9 #define RI_EXCPT 10 #define OVF_EXCPT 12 /* Floating point exceptions (Ch. 8): */ #define INEXACT_EXCEPT 13 #define INVALID_EXCEPT 14 #define DIV0_EXCEPT 15 #define FOVF_EXCEPT 16 #define FUNF_EXCEPT 17 #define LAST_REAL_EXCEPT FUNF_EXCEPT /* External interrupts: */ #define CLOCK_EXCPT 0x100 /* IP[0] */ #define IO_EXCPT 0x200 /* IP[1] */ extern void text_begins_at_point(unsigned long addr); extern void k_text_begins_at_point(unsigned long addr); extern unsigned long current_text_pc(void); extern void increment_text_pc(int delta); extern void user_kernel_text_segment(int to_kernel); extern void store_instruction(instruction *inst); extern void i_type_inst(int opcode,int rt,int rs,imm_expr *expr); extern void j_type_inst(int opcode,imm_expr *target); extern void r_type_inst(int opcode,int rd,int rs,int rt); extern void r_sh_type_inst(int opcode,int rd,int rt,int shamt); extern void r_cond_type_inst(int opcode,int rs,int rt); extern void print_inst(unsigned long addr); extern int print_inst_internal(char *buf,instruction *inst,unsigned long addr); extern int opcode_is_branch(int opcode); extern int opcode_is_jump(int opcode); extern int opcode_is_load_store(int opcode); extern int inst_is_breakpoint(unsigned long addr); extern instruction *set_breakpoint(unsigned long addr); extern imm_expr *make_imm_expr(int offs,char *sym,int pc_rel); extern imm_expr *copy_imm_expr(imm_expr *old_expr); extern imm_expr *upper_bits_of_expr(imm_expr *old_expr); extern imm_expr *lower_bits_of_expr(imm_expr *old_expr); extern imm_expr *const_imm_expr(long value); extern imm_expr *incr_expr_offset(imm_expr *expr,long value); extern long eval_imm_expr(imm_expr *expr); extern int zero_imm(imm_expr *expr); extern addr_expr *make_addr_expr(long offs,char *sym,int reg_no); extern imm_expr *addr_expr_imm(addr_expr *expr); extern int addr_expr_reg(addr_expr *expr); extern long inst_encode(instruction *inst); extern instruction *inst_decode(long value); extern void test_assembly(instruction *inst);