"I am a person who works hard and plays hard."

Yuan Wei
Second Year Graduate Student Department of Computer Science
University of Virginia Charlottesville, VA 22903
Email: yw3f@cs.virginia.edu


Source Code Analysis

Main Page   Compound List   File List   Compound Members   File Members  

pisa.h

Go to the documentation of this file.
00001 /*
00002  * pisa.h - SimpleScaler portable ISA (pisa) definitions
00003  *
00004  * This file is a part of the SimpleScalar tool suite written by
00005  * Todd M. Austin as a part of the Multiscalar Research Project.
00006  *  
00007  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00008  * 
00009  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00010  *
00011  * This source file is distributed "as is" in the hope that it will be
00012  * useful.  The tool set comes with no warranty, and no author or
00013  * distributor accepts any responsibility for the consequences of its
00014  * use. 
00015  * 
00016  * Everyone is granted permission to copy, modify and redistribute
00017  * this tool set under the following conditions:
00018  * 
00019  *    This source code is distributed for non-commercial use only. 
00020  *    Please contact the maintainer for restrictions applying to 
00021  *    commercial use.
00022  *
00023  *    Permission is granted to anyone to make or distribute copies
00024  *    of this source code, either as received or modified, in any
00025  *    medium, provided that all copyright notices, permission and
00026  *    nonwarranty notices are preserved, and that the distributor
00027  *    grants the recipient permission for further redistribution as
00028  *    permitted by this document.
00029  *
00030  *    Permission is granted to distribute this file in compiled
00031  *    or executable form under the same conditions that apply for
00032  *    source code, provided that either:
00033  *
00034  *    A. it is accompanied by the corresponding machine-readable
00035  *       source code,
00036  *    B. it is accompanied by a written offer, with no time limit,
00037  *       to give anyone a machine-readable copy of the corresponding
00038  *       source code in return for reimbursement of the cost of
00039  *       distribution.  This written offer must permit verbatim
00040  *       duplication by anyone, or
00041  *    C. it is distributed by someone who received only the
00042  *       executable form, and is accompanied by a copy of the
00043  *       written offer of source code that they received concurrently.
00044  *
00045  * In other words, you are welcome to use, share and improve this
00046  * source file.  You are forbidden to forbid anyone else to use, share
00047  * and improve what you give them.
00048  *
00049  * INTERNET: dburger@cs.wisc.edu
00050  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00051  *
00052  * $Id: pisa.h,v 1.1.1.1 2000/05/26 15:21:54 taustin Exp $
00053  *
00054  * $Log: pisa.h,v $
00055  * Revision 1.1.1.1  2000/05/26 15:21:54  taustin
00056  * SimpleScalar Tool Set
00057  *
00058  *
00059  * Revision 1.9  1999/12/31 19:03:38  taustin
00060  * quad_t naming conflicts removed
00061  *
00062  * Revision 1.8  1999/12/13 19:00:56  taustin
00063  * cross endian execution support added
00064  *
00065  * Revision 1.7  1998/08/31 17:13:14  taustin
00066  * added register checksuming routines
00067  *
00068  * Revision 1.6  1998/08/27 17:05:36  taustin
00069  * added target interface support
00070  * moved target-dependent definitions to target files
00071  * added support for register and memory contexts
00072  * LWL/LWR/SWL/SWR semantics fixed in ss.def, these instruction now
00073  *       appear to work correctly on big- and little-endian machines, this
00074  *       fixes all previous problems with IJPEG failing during functional
00075  *       simulation
00076  *
00077  *
00078  */
00079 
00080 #ifndef PISA_H
00081 #define PISA_H
00082 
00083 #include <stdio.h>
00084 
00085 #include "host.h"
00086 #include "misc.h"
00087 #include "config.h"
00088 #include "endian.h"
00089 
00090 /*
00091  * This file contains various definitions needed to decode, disassemble, and
00092  * execute PISA (portable ISA) instructions.
00093  */
00094 
00095 /* build for PISA target */
00096 #define TARGET_PISA
00097 
00098 #ifndef TARGET_PISA_BIG
00099 #ifndef TARGET_PISA_LITTLE
00100 /* no cross-endian support, default to host endian */
00101 #ifdef BYTES_BIG_ENDIAN
00102 #define TARGET_PISA_BIG
00103 #else
00104 #define TARGET_PISA_LITTLE
00105 #endif
00106 #endif /* TARGET_PISA_LITTLE */
00107 #endif /* TARGET_PISA_BIG */
00108 
00109 /* probe cross-endian execution */
00110 #if defined(BYTES_BIG_ENDIAN) && defined(TARGET_PISA_LITTLE)
00111 #define MD_CROSS_ENDIAN
00112 #endif
00113 #if defined(BYTES_LITTLE_ENDIAN) && defined(TARGET_PISA_BIG)
00114 #define MD_CROSS_ENDIAN
00115 #endif
00116 
00117 /* not applicable/available, usable in most definition contexts */
00118 #define NA              0
00119 
00120 /*
00121  * target-dependent type definitions
00122  */
00123 
00124 /* define MD_QWORD_ADDRS if the target requires 64-bit (qword) addresses */
00125 #undef MD_QWORD_ADDRS
00126 
00127 /* address type definition */
00128 typedef word_t md_addr_t;
00129 
00130 
00131 /*
00132  * target-dependent memory module configuration
00133  */
00134 
00135 /* physical memory page size (must be a power-of-two) */
00136 #define MD_PAGE_SIZE            4096
00137 #define MD_LOG_PAGE_SIZE        12
00138 
00139 
00140 /*
00141  * target-dependent instruction faults
00142  */
00143 
00144 enum md_fault_type {
00145   md_fault_none = 0,            /* no fault */
00146   md_fault_access,              /* storage access fault */
00147   md_fault_alignment,           /* storage alignment fault */
00148   md_fault_overflow,            /* signed arithmetic overflow fault */
00149   md_fault_div0,                /* division by zero fault */
00150   md_fault_break,               /* BREAK instruction fault */
00151   md_fault_unimpl,              /* unimplemented instruction fault */
00152   md_fault_internal             /* internal S/W fault */
00153 };
00154 
00155 
00156 /*
00157  * target-dependent register file definitions, used by regs.[hc]
00158  */
00159 
00160 /* number of integer registers */
00161 #define MD_NUM_IREGS            32
00162 
00163 /* number of floating point registers */
00164 #define MD_NUM_FREGS            32
00165 
00166 /* number of control registers */
00167 #define MD_NUM_CREGS            3
00168 
00169 /* total number of registers, excluding PC and NPC */
00170 #define MD_TOTAL_REGS                                                   \
00171   (/*int*/32 + /*fp*/32 + /*misc*/3 + /*tmp*/1 + /*mem*/1 + /*ctrl*/1)
00172 
00173 /* general purpose (integer) register file entry type */
00174 typedef sword_t md_gpr_t[MD_NUM_IREGS];
00175 
00176 /* floating point register file entry type */
00177 typedef union {
00178   sword_t l[MD_NUM_FREGS];      /* integer word view */
00179   sfloat_t f[MD_NUM_FREGS];     /* single-precision floating point view */
00180   dfloat_t d[MD_NUM_FREGS/2];   /* double-prediction floating point view */
00181 } md_fpr_t;
00182 
00183 /* control register file contents */
00184 typedef struct {
00185   sword_t hi, lo;               /* multiplier HI/LO result registers */
00186   int fcc;                      /* floating point condition codes */
00187 } md_ctrl_t;
00188 
00189 /* well known registers */
00190 enum md_reg_names {
00191   MD_REG_ZERO = 0,      /* zero register */
00192   MD_REG_GP = 28,       /* global data section pointer */
00193   MD_REG_SP = 29,       /* stack pointer */
00194   MD_REG_FP = 30        /* frame pointer */
00195 };
00196 
00197 
00198 /*
00199  * target-dependent instruction format definition
00200  */
00201 
00202 /* instruction formats */
00203 typedef struct {
00204   word_t a;             /* simplescalar opcode (must be unsigned) */
00205   word_t b;             /* simplescalar unsigned immediate fields */
00206 } md_inst_t;
00207 
00208 /* preferred nop instruction definition */
00209 extern md_inst_t MD_NOP_INST;
00210 
00211 /* target swap support */
00212 #ifdef MD_CROSS_ENDIAN
00213 
00214 #define MD_SWAPH(X)             SWAP_HALF(X)
00215 #define MD_SWAPW(X)             SWAP_WORD(X)
00216 #define MD_SWAPQ(X)             SWAP_QWORD(X)
00217 #define MD_SWAPI(X)             ((X).a = SWAP_WORD((X).a),              \
00218                                  (X).b = SWAP_WORD((X).b))
00219 
00220 #else /* !MD_CROSS_ENDIAN */
00221 
00222 #define MD_SWAPH(X)             (X)
00223 #define MD_SWAPW(X)             (X)
00224 #define MD_SWAPQ(X)             (X)
00225 #define MD_SWAPD(X)             (X)
00226 #define MD_SWAPI(X)             (X)
00227 
00228 #endif
00229 
00230 /* fetch an instruction */
00231 #define MD_FETCH_INST(INST, MEM, PC)                                    \
00232   { inst.a = MEM_READ_WORD(mem, (PC));                                  \
00233     inst.b = MEM_READ_WORD(mem, (PC) + sizeof(word_t)); }
00234 
00235 /*
00236  * target-dependent loader module configuration
00237  */
00238 
00239 /* virtual memory segment limits */
00240 #define MD_TEXT_BASE            0x00400000
00241 #define MD_DATA_BASE            0x10000000
00242 #define MD_STACK_BASE           0x7fffc000
00243 
00244 /* maximum size of argc+argv+envp environment */
00245 #define MD_MAX_ENVIRON          16384
00246 
00247 
00248 /*
00249  * machine.def specific definitions
00250  */
00251 
00252 /* returns the opcode field value of SimpleScalar instruction INST */
00253 #define MD_OPFIELD(INST)                (INST.a & 0xff)
00254 #define MD_SET_OPCODE(OP, INST) ((OP) = ((INST).a & 0xff))
00255 
00256 /* largest opcode field value (currently upper 8-bit are used for pre/post-
00257    incr/decr operation specifiers */
00258 #define MD_MAX_MASK             255
00259 
00260 /* global opcode names, these are returned by the decoder (MD_OP_ENUM()) */
00261 enum md_opcode {
00262   OP_NA = 0,    /* NA */
00263 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) OP,
00264 #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) OP,
00265 #define CONNECT(OP)
00266 #include "machine.def"
00267   OP_MAX        /* number of opcodes + NA */
00268 };
00269 
00270 /* inst -> enum md_opcode mapping, use this macro to decode insts */
00271 #define MD_OP_ENUM(MSK)         (md_mask2op[MSK])
00272 extern enum md_opcode md_mask2op[];
00273 
00274 /* enum md_opcode -> description string */
00275 #define MD_OP_NAME(OP)          (md_op2name[OP])
00276 extern char *md_op2name[];
00277 
00278 /* enum md_opcode -> opcode operand format, used by disassembler */
00279 #define MD_OP_FORMAT(OP)        (md_op2format[OP])
00280 extern char *md_op2format[];
00281 
00282 /* function unit classes, update md_fu2name if you update this definition */
00283 enum md_fu_class {
00284   FUClass_NA = 0,       /* inst does not use a functional unit */
00285   IntALU,               /* integer ALU */
00286   IntMULT,              /* integer multiplier */
00287   IntDIV,               /* integer divider */
00288   FloatADD,             /* floating point adder/subtractor */
00289   FloatCMP,             /* floating point comparator */
00290   FloatCVT,             /* floating point<->integer converter */
00291   FloatMULT,            /* floating point multiplier */
00292   FloatDIV,             /* floating point divider */
00293   FloatSQRT,            /* floating point square root */
00294   RdPort,               /* memory read port */
00295   WrPort,               /* memory write port */
00296   NUM_FU_CLASSES        /* total functional unit classes */
00297 };
00298 
00299 /* enum md_opcode -> enum md_fu_class, used by performance simulators */
00300 #define MD_OP_FUCLASS(OP)       (md_op2fu[OP])
00301 extern enum md_fu_class md_op2fu[];
00302 
00303 /* enum md_fu_class -> description string */
00304 #define MD_FU_NAME(FU)          (md_fu2name[FU])
00305 extern char *md_fu2name[];
00306 
00307 /* instruction flags */
00308 #define F_ICOMP         0x00000001      /* integer computation */
00309 #define F_FCOMP         0x00000002      /* FP computation */
00310 #define F_CTRL          0x00000004      /* control inst */
00311 #define F_UNCOND        0x00000008      /*   unconditional change */
00312 #define F_COND          0x00000010      /*   conditional change */
00313 #define F_MEM           0x00000020      /* memory access inst */
00314 #define F_LOAD          0x00000040      /*   load inst */
00315 #define F_STORE         0x00000080      /*   store inst */
00316 #define F_DISP          0x00000100      /*   displaced (R+C) addr mode */
00317 #define F_RR            0x00000200      /*   R+R addr mode */
00318 #define F_DIRECT        0x00000400      /*   direct addressing mode */
00319 #define F_TRAP          0x00000800      /* traping inst */
00320 #define F_LONGLAT       0x00001000      /* long latency inst (for sched) */
00321 #define F_DIRJMP        0x00002000      /* direct jump */
00322 #define F_INDIRJMP      0x00004000      /* indirect jump */
00323 #define F_CALL          0x00008000      /* function call */
00324 #define F_FPCOND        0x00010000      /* FP conditional branch */
00325 #define F_IMM           0x00020000      /* instruction has immediate operand */
00326 
00327 /* enum md_opcode -> opcode flags, used by simulators */
00328 #define MD_OP_FLAGS(OP)         (md_op2flags[OP])
00329 extern unsigned int md_op2flags[];
00330 
00331 /* integer register specifiers */
00332 #undef  RS      /* defined in /usr/include/sys/syscall.h on HPUX boxes */
00333 #define RS              (inst.b >> 24)                  /* reg source #1 */
00334 #define RT              ((inst.b >> 16) & 0xff)         /* reg source #2 */
00335 #define RD              ((inst.b >> 8) & 0xff)          /* reg dest */
00336 
00337 /* returns shift amount field value */
00338 #define SHAMT           (inst.b & 0xff)
00339 
00340 /* floating point register field synonyms */
00341 #define FS              RS
00342 #define FT              RT
00343 #define FD              RD
00344 
00345 /* returns 16-bit signed immediate field value */
00346 #define IMM             ((int)((/* signed */short)(inst.b & 0xffff)))
00347 
00348 /* returns 16-bit unsigned immediate field value */
00349 #define UIMM            (inst.b & 0xffff)
00350 
00351 /* returns 26-bit unsigned absolute jump target field value */
00352 #define TARG            (inst.b & 0x3ffffff)
00353 
00354 /* returns break code immediate field value */
00355 #define BCODE           (inst.b & 0xfffff)
00356 
00357 /* load/store 16-bit signed offset field value, synonym for imm field */
00358 #define OFS             IMM             /* alias to IMM */
00359 
00360 /* load/store base register specifier, synonym for RS field */
00361 #define BS              RS              /* alias to rs */
00362 
00363 /* largest signed integer */
00364 #define MAXINT_VAL      0x7fffffff
00365 
00366 /* check for overflow in X+Y, both signed */
00367 #define OVER(X,Y)                                                       \
00368   ((((X) > 0) && ((Y) > 0) && (MAXINT_VAL - (X) < (Y)))                 \
00369    || (((X) < 0) && ((Y) < 0) && (-MAXINT_VAL - (X) > (Y))))
00370 
00371 /* check for underflow in X-Y, both signed */
00372 #define UNDER(X,Y)                                                      \
00373   ((((X) > 0) && ((Y) < 0) && (MAXINT_VAL + (Y) < (X)))                 \
00374    || (((X) < 0) && ((Y) > 0) && (-MAXINT_VAL + (Y) > (X))))
00375 
00376 /* default target PC handling */
00377 #ifndef SET_TPC
00378 #define SET_TPC(PC)     (void)0
00379 #endif /* SET_TPC */
00380 
00381 #ifdef BYTES_BIG_ENDIAN
00382 /* lwl/swl defs */
00383 #define WL_SIZE(ADDR)           ((ADDR) & 0x03)
00384 #define WL_BASE(ADDR)           ((ADDR) & ~0x03)
00385 #define WL_PROT_MASK(ADDR)      (md_lr_masks[4-WL_SIZE(ADDR)])
00386 #define WL_PROT_MASK1(ADDR)     (md_lr_masks[WL_SIZE(ADDR)])
00387 #define WL_PROT_MASK2(ADDR)     (md_lr_masks[4-WL_SIZE(ADDR)])
00388 
00389 /* lwr/swr defs */
00390 #define WR_SIZE(ADDR)           (((ADDR) & 0x03)+1)
00391 #define WR_BASE(ADDR)           ((ADDR) & ~0x03)
00392 #define WR_PROT_MASK(ADDR)      (~(md_lr_masks[WR_SIZE(ADDR)]))
00393 #define WR_PROT_MASK1(ADDR)     ((md_lr_masks[WR_SIZE(ADDR)]))
00394 #define WR_PROT_MASK2(ADDR)     (md_lr_masks[4-WR_SIZE(ADDR)])
00395 #else /* BYTES_LITTLE_ENDIAN */
00396 /* lwl/swl defs */
00397 #define WL_SIZE(ADDR)           (4-((ADDR) & 0x03))
00398 #define WL_BASE(ADDR)           ((ADDR) & ~0x03)
00399 #define WL_PROT_MASK(ADDR)      (md_lr_masks[4-WL_SIZE(ADDR)])
00400 #define WL_PROT_MASK1(ADDR)     (md_lr_masks[WL_SIZE(ADDR)])
00401 #define WL_PROT_MASK2(ADDR)     (md_lr_masks[4-WL_SIZE(ADDR)])
00402 
00403 /* lwr/swr defs */
00404 #define WR_SIZE(ADDR)           (((ADDR) & 0x03)+1)
00405 #define WR_BASE(ADDR)           ((ADDR) & ~0x03)
00406 #define WR_PROT_MASK(ADDR)      (~(md_lr_masks[WR_SIZE(ADDR)]))
00407 #define WR_PROT_MASK1(ADDR)     ((md_lr_masks[WR_SIZE(ADDR)]))
00408 #define WR_PROT_MASK2(ADDR)     (md_lr_masks[4-WR_SIZE(ADDR)])
00409 #endif
00410   
00411 /* mask table used to speed up LWL/LWR implementation */
00412 extern word_t md_lr_masks[];
00413 
00414 #if 0
00415 /* lwl/swl defs */
00416 #define WL_SIZE(ADDR)       (4-((ADDR) & 0x03))
00417 #define WL_BASE(ADDR)       ((ADDR) & ~0x03)
00418 #define WL_PROT_MASK(ADDR)  (md_lr_masks[4-WL_SIZE(ADDR)])
00419 
00420 /* lwr/swr defs */
00421 #define WR_SIZE(ADDR)       (((ADDR) & 0x03)+1)
00422 #define WR_BASE(ADDR)       ((ADDR) & ~0x03)
00423 #define WR_PROT_MASK(ADDR)  (~(md_lr_masks[WR_SIZE(ADDR)]))
00424 /* #else */
00425 /* lwl/swl stuff */
00426 #define WL_SIZE(ADDR)           ((ADDR) & 0x03)
00427 #define WL_BASE(ADDR)           ((ADDR) & ~0x03)
00428 #define WL_PROT_MASK1(ADDR)     (md_lr_masks[WL_SIZE(ADDR)])
00429 #define WL_PROT_MASK2(ADDR)     (md_lr_masks[4-WL_SIZE(ADDR)])
00430 
00431 /* lwr/swr stuff */
00432 #define WR_SIZE(ADDR)           (((ADDR) & 0x03)+1)
00433 #define WR_BASE(ADDR)           ((ADDR) & ~0x03)
00434 #define WR_PROT_MASK1(ADDR)     ((md_lr_masks[WR_SIZE(ADDR)]))
00435 #define WR_PROT_MASK2(ADDR)     (md_lr_masks[4-WR_SIZE(ADDR)])
00436 #endif
00437 
00438 
00439 /*
00440  * various other helper macros/functions
00441  */
00442 
00443 /* non-zero if system call is an exit() */
00444 #define SS_SYS_exit                     1
00445 #define MD_EXIT_SYSCALL(REGS)           ((REGS)->regs_R[2] == SS_SYS_exit)
00446 
00447 /* non-zero if system call is a write to stdout/stderr */
00448 #define SS_SYS_write            4
00449 #define MD_OUTPUT_SYSCALL(REGS)                                         \
00450   ((REGS)->regs_R[2] == SS_SYS_write                                    \
00451    && ((REGS)->regs_R[4] == /* stdout */1                               \
00452        || (REGS)->regs_R[4] == /* stderr */2))
00453 
00454 /* returns stream of an output system call, translated to host */
00455 #define MD_STREAM_FILENO(REGS)          ((REGS)->regs_R[4])
00456 
00457 /* returns non-zero if instruction is a function call */
00458 #define MD_IS_CALL(OP)                                                  \
00459   ((MD_OP_FLAGS(OP) & (F_CTRL|F_CALL)) == (F_CTRL|F_CALL))
00460 
00461 /* returns non-zero if instruction is a function return */
00462 #define MD_IS_RETURN(OP)                ((OP) == JR && (RS) == 31)
00463 
00464 /* returns non-zero if instruction is an indirect jump */
00465 #define MD_IS_INDIR(OP)                 ((OP) == JR)
00466 
00467 /* addressing mode probe, enums and strings */
00468 enum md_amode_type {
00469   md_amode_imm,         /* immediate addressing mode */
00470   md_amode_gp,          /* global data access through global pointer */
00471   md_amode_sp,          /* stack access through stack pointer */
00472   md_amode_fp,          /* stack access through frame pointer */
00473   md_amode_disp,        /* (reg + const) addressing */
00474   md_amode_rr,          /* (reg + reg) addressing */
00475   md_amode_NUM
00476 };
00477 extern char *md_amode_str[md_amode_NUM];
00478 
00479 /* addressing mode pre-probe FSM, must see all instructions */
00480 #define MD_AMODE_PREPROBE(OP, FSM)                                      \
00481   { if ((OP) == LUI) (FSM) = (RT); }
00482 
00483 /* compute addressing mode, only for loads/stores */
00484 #define MD_AMODE_PROBE(AM, OP, FSM)                                     \
00485   {                                                                     \
00486     if (MD_OP_FLAGS(OP) & F_DISP)                                       \
00487       {                                                                 \
00488         if ((BS) == (FSM))                                              \
00489           (AM) = md_amode_imm;                                          \
00490         else if ((BS) == MD_REG_GP)                                     \
00491           (AM) = md_amode_gp;                                           \
00492         else if ((BS) == MD_REG_SP)                                     \
00493           (AM) = md_amode_sp;                                           \
00494         else if ((BS) == MD_REG_FP) /* && bind_to_seg(addr) == seg_stack */\
00495           (AM) = md_amode_fp;                                           \
00496         else                                                            \
00497           (AM) = md_amode_disp;                                         \
00498       }                                                                 \
00499     else if (MD_OP_FLAGS(OP) & F_RR)                                    \
00500       (AM) = md_amode_rr;                                               \
00501     else                                                                \
00502       panic("cannot decode addressing mode");                           \
00503   }
00504 
00505 /* addressing mode pre-probe FSM, after all loads and stores */
00506 #define MD_AMODE_POSTPROBE(FSM)                                         \
00507   { (FSM) = MD_REG_ZERO; }
00508 
00509 
00510 /*
00511  * EIO package configuration/macros
00512  */
00513 
00514 /* expected EIO file format */
00515 #define MD_EIO_FILE_FORMAT              EIO_PISA_FORMAT
00516 
00517 #define MD_MISC_REGS_TO_EXO(REGS)                                       \
00518   exo_new(ec_list,                                                      \
00519           /*icnt*/exo_new(ec_integer, (exo_integer_t)sim_num_insn),     \
00520           /*PC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_PC),    \
00521           /*NPC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_NPC),  \
00522           /*HI*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.hi),  \
00523           /*LO*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.lo),  \
00524           /*FCC*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fcc),\
00525           NULL)
00526 
00527 #define MD_IREG_TO_EXO(REGS, IDX)                                       \
00528   exo_new(ec_address, (exo_integer_t)(REGS)->regs_R[IDX])
00529 
00530 #define MD_FREG_TO_EXO(REGS, IDX)                                       \
00531   exo_new(ec_address, (exo_integer_t)(REGS)->regs_F.l[IDX])
00532 
00533 #define MD_EXO_TO_MISC_REGS(EXO, ICNT, REGS)                            \
00534   /* check EXO format for errors... */                                  \
00535   if (!exo                                                              \
00536       || exo->ec != ec_list                                             \
00537       || !exo->as_list.head                                             \
00538       || exo->as_list.head->ec != ec_integer                            \
00539       || !exo->as_list.head->next                                       \
00540       || exo->as_list.head->next->ec != ec_address                      \
00541       || !exo->as_list.head->next->next                                 \
00542       || exo->as_list.head->next->next->ec != ec_address                \
00543       || !exo->as_list.head->next->next->next                           \
00544       || exo->as_list.head->next->next->next->ec != ec_integer          \
00545       || !exo->as_list.head->next->next->next->next                     \
00546       || exo->as_list.head->next->next->next->next->ec != ec_integer    \
00547       || !exo->as_list.head->next->next->next->next->next               \
00548       || exo->as_list.head->next->next->next->next->next->ec != ec_integer\
00549       || exo->as_list.head->next->next->next->next->next->next != NULL) \
00550     fatal("could not read EIO misc regs");                              \
00551   (ICNT) = (counter_t)exo->as_list.head->as_integer.val;                \
00552   (REGS)->regs_PC = (md_addr_t)exo->as_list.head->next->as_address.val; \
00553   (REGS)->regs_NPC =                                                    \
00554     (md_addr_t)exo->as_list.head->next->next->as_address.val;           \
00555   (REGS)->regs_C.hi =                                                   \
00556     (word_t)exo->as_list.head->next->next->next->as_integer.val;        \
00557   (REGS)->regs_C.lo =                                                   \
00558     (word_t)exo->as_list.head->next->next->next->next->as_integer.val;  \
00559   (REGS)->regs_C.fcc =                                                  \
00560     (int)exo->as_list.head->next->next->next->next->next->as_integer.val;
00561 
00562 #define MD_EXO_TO_IREG(EXO, REGS, IDX)                                  \
00563   ((REGS)->regs_R[IDX] = (word_t)(EXO)->as_integer.val)
00564 
00565 #define MD_EXO_TO_FREG(EXO, REGS, IDX)                                  \
00566   ((REGS)->regs_F.l[IDX] = (word_t)(EXO)->as_integer.val)
00567 
00568 #define MD_EXO_CMP_IREG(EXO, REGS, IDX)                                 \
00569   ((REGS)->regs_R[IDX] != (sword_t)(EXO)->as_integer.val)
00570 
00571 #define MD_FIRST_IN_REG                 2
00572 #define MD_LAST_IN_REG                  7
00573 
00574 #define MD_FIRST_OUT_REG                2
00575 #define MD_LAST_OUT_REG                 7
00576 
00577 
00578 /*
00579  * configure the EXO package
00580  */
00581 
00582 /* EXO pointer class */
00583 typedef qword_t exo_address_t;
00584 
00585 /* EXO integer class, 64-bit encoding */
00586 typedef qword_t exo_integer_t;
00587 
00588 /* EXO floating point class, 64-bit encoding */
00589 typedef double exo_float_t;
00590 
00591 
00592 /*
00593  * configure the stats package
00594  */
00595 
00596 /* counter stats */
00597 #ifdef HOST_HAS_QWORD
00598 #define stat_reg_counter                stat_reg_sqword
00599 #define sc_counter                      sc_sqword
00600 #define for_counter                     for_sqword
00601 #else /* !HOST_HAS_QWORD */
00602 #define stat_reg_counter                stat_reg_double
00603 #define sc_counter                      sc_double
00604 #define for_counter                     for_double
00605 #endif /* HOST_HAS_QWORD */
00606 
00607 /* address stats */
00608 #define stat_reg_addr                   stat_reg_uint
00609 
00610 
00611 /*
00612  * configure the DLite! debugger
00613  */
00614 
00615 /* register bank specifier */
00616 enum md_reg_type {
00617   rt_gpr,               /* general purpose register */
00618   rt_lpr,               /* integer-precision floating pointer register */
00619   rt_fpr,               /* single-precision floating pointer register */
00620   rt_dpr,               /* double-precision floating pointer register */
00621   rt_ctrl,              /* control register */
00622   rt_PC,                /* program counter */
00623   rt_NPC,               /* next program counter */
00624   rt_NUM
00625 };
00626 
00627 /* register name specifier */
00628 struct md_reg_names_t {
00629   char *str;                    /* register name */
00630   enum md_reg_type file;        /* register file */
00631   int reg;                      /* register index */
00632 };
00633 
00634 /* symbolic register names, parser is case-insensitive */
00635 extern struct md_reg_names_t md_reg_names[];
00636 
00637 /* returns a register name string */
00638 char *md_reg_name(enum md_reg_type rt, int reg);
00639 
00640 /* default register accessor object */
00641 struct eval_value_t;
00642 struct regs_t;
00643 char *                                          /* err str, NULL for no err */
00644 md_reg_obj(struct regs_t *regs,                 /* registers to access */
00645            int is_write,                        /* access type */
00646            enum md_reg_type rt,                 /* reg bank to probe */
00647            int reg,                             /* register number */
00648            struct eval_value_t *val);           /* input, output */
00649 
00650 /* print integer REG(S) to STREAM */
00651 void md_print_ireg(md_gpr_t regs, int reg, FILE *stream);
00652 void md_print_iregs(md_gpr_t regs, FILE *stream);
00653 
00654 /* print floating point REG(S) to STREAM */
00655 void md_print_fpreg(md_fpr_t regs, int reg, FILE *stream);
00656 void md_print_fpregs(md_fpr_t regs, FILE *stream);
00657 
00658 /* print control REG(S) to STREAM */
00659 void md_print_creg(md_ctrl_t regs, int reg, FILE *stream);
00660 void md_print_cregs(md_ctrl_t regs, FILE *stream);
00661 
00662 /* compute CRC of all registers */
00663 word_t md_crc_regs(struct regs_t *regs);
00664 
00665 /* xor checksum registers */
00666 word_t md_xor_regs(struct regs_t *regs);
00667 
00668 
00669 /*
00670  * configure sim-outorder specifics
00671  */
00672 
00673 /* primitive operation used to compute addresses within pipeline */
00674 #define MD_AGEN_OP              ADD
00675 
00676 /* NOP operation when injected into the pipeline */
00677 #define MD_NOP_OP               NOP
00678 
00679 /* non-zero for a valid address, used to determine if speculative accesses
00680    should access the DL1 data cache */
00681 #define MD_VALID_ADDR(ADDR)                                             \
00682   (((ADDR) >= ld_text_base && (ADDR) < (ld_text_base + ld_text_size))   \
00683    || ((ADDR) >= ld_data_base && (ADDR) < ld_stack_base))
00684 
00685 
00686 /*
00687  * configure branch predictors
00688  */
00689 
00690 /* shift used to ignore branch address least significant bits, usually
00691    log2(sizeof(md_inst_t)) */
00692 #define MD_BR_SHIFT             3       /* log2(8) */
00693 
00694 
00695 /*
00696  * target-dependent routines
00697  */
00698 
00699 /* intialize the inst decoder, this function builds the ISA decode tables */
00700 void md_init_decoder(void);
00701 
00702 /* disassemble an instruction */
00703 void
00704 md_print_insn(md_inst_t inst,           /* instruction to disassemble */
00705               md_addr_t pc,             /* addr of inst, used for PC-rels */
00706               FILE *stream);            /* output stream */
00707 
00708 #endif /* PISA_H */
00709 
00710 
00711 
00712 
00713 
00714 
00715 
00716 
00717 
00718 
00719 
00720 
00721 
00722 
00723 
00724 
00725 
00726 #if 0
00727 
00728 /* virtual memory page size, this should be user configurable */
00729 #define SS_PAGE_SIZE            4096
00730 
00731 /* total number of registers in each register file (int and FP) */
00732 #define SS_NUM_REGS             32
00733 
00734 /* total number of register in processor 32I+32F+HI+LO+FCC+TMP+MEM+CTRL */
00735 #define SS_TOTAL_REGS                                                   \
00736   (SS_NUM_REGS+SS_NUM_REGS+/*HI*/1+/*LO*/1+/*FCC*/1+/*TMP*/1+           \
00737    /*MEM*/1+/*CTRL*/1)
00738 
00739 /* returns pre/post-incr/decr operation field value */
00740 #define SS_COMP_OP              ((inst.a & 0xff00) >> 8)
00741 
00742 /* pre/post-incr/decr operation field specifiers */
00743 #define SS_COMP_NOP             0x00
00744 #define SS_COMP_POST_INC        0x01
00745 #define SS_COMP_POST_DEC        0x02
00746 #define SS_COMP_PRE_INC         0x03
00747 #define SS_COMP_PRE_DEC         0x04
00748 #define SS_COMP_POST_DBL_INC    0x05    /* for double word accesses */
00749 #define SS_COMP_POST_DBL_DEC    0x06
00750 #define SS_COMP_PRE_DBL_INC     0x07
00751 #define SS_COMP_PRE_DBL_DEC     0x08
00752 
00753 /* the instruction expression modifications required for an expression to
00754    support pre/post-incr/decr operations is accomplished by the INC_DEC()
00755    macro, it looks so contorted to reduce the control complexity of the
00756    equation (and thus reducing the compilation time greatly with GNU GCC -
00757    the key is to only emit EXPR one time) */
00758 #define INC_DEC(EXPR, REG, SIZE)                                        \
00759   (SET_GPR((REG), GPR(REG) + ss_fore_tab[(SIZE)-1][SS_COMP_OP]),        \
00760    (EXPR),                                                              \
00761    SET_GPR((REG), GPR(REG) + ss_aft_tab[(SIZE)-1][SS_COMP_OP]))
00762 
00763 /* INC_DEC expression step tables, they map (operation, size) -> step value */
00764 extern int ss_fore_tab[8][5];
00765 extern int ss_aft_tab[8][5];
00766 
00767 /* pre-defined registers */
00768 #define Rgp             28              /* global data pointer */
00769 #define Rsp             29              /* stack pointer */
00770 #define Rfp             30              /* frame pointer */
00771 
00772 /* FIXME: non-reentrant LWL/LWR implementation workspace */
00773 extern SS_ADDR_TYPE ss_lr_temp;
00774 
00775 /* FIXME: non-reentrant temporary variables */
00776 extern SS_ADDR_TYPE temp_bs, temp_rd;
00777 
00778 /* instruction failure notification macro, this can be defined by the
00779    target simulator if, for example, the simulator wants to handle the
00780    instruction fault in a machine specific fashion; a string describing
00781    the instruction fault is passed to the IFAIL() macro */
00782 #ifndef IFAIL
00783 #define IFAIL(S)        fatal(S)
00784 #endif /* IFAIL */
00785 
00786 /* check for divide by zero error, N is denom */
00787 #define DIV0(N)         (((N) == 0) ? IFAIL("divide by 0") : (void)0)
00788 
00789 /* check reg specifier N for required double integer word alignment */
00790 #define INTALIGN(N)     (((N) & 01)                                     \
00791                          ? IFAIL("bad INT register alignment") : (void)0)
00792 
00793 /* check reg specifier N for required double FP word alignment */
00794 #define FPALIGN(N)      (((N) & 01)                                     \
00795                          ? IFAIL("bad FP register alignment") : (void)0)
00796 
00797 /* check target address TARG for required jump target alignment */
00798 #define TALIGN(TARG)    (((TARG) & 0x7)                                 \
00799                          ? IFAIL("bad jump alignment") : (void)0)
00800 /* inst checks disables, change all checks to NOP expressions */
00801 #define OVER(X,Y)       ((void)0)
00802 #define UNDER(X,Y)      ((void)0)
00803 #define DIV0(N)         ((void)0)
00804 #define INTALIGN(N)     ((void)0)
00805 #define FPALIGN(N)      ((void)0)
00806 #define TALIGN(TARG)    ((void)0)
00807 
00808 /* default division operator semantics, this operation is accessed through a
00809    macro because some simulators need to check for divide by zero faults
00810    before executing this operation */
00811 #define IDIV(A, B)      ((A) / (B))
00812 #define IMOD(A, B)      ((A) % (B))
00813 #define FDIV(A, B)      ((A) / (B))
00814 #define FINT(A)         ((int)A)
00815 
00816 #endif


UVa CS Department of Computer Science
School of Engineering, University of Virginia
151 Engineer's Way, P.O. Box 400740
Charlottesville, Virginia 22904-4740

(434) 982-2200  Fax: (434) 982-2214