• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/core/techModels/libsim-panalyzer/target-pisa/pisa.h

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

Generated on Fri Oct 22 2010 11:02:21 for SST by  doxygen 1.7.1