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

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

00001 /*
00002  * arm.h - ARM ISA 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: arm.h,v 1.1.1.1 2003/09/18 00:57:55 panalyzer Exp $
00053  *
00054  * $Log: arm.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.2.17  2000/11/21 14:52:08  taustin
00069  * Completed changes for SA-1 core validation.
00070  *
00071  * Revision 1.1.2.16  2000/09/26 15:45:38  taustin
00072  * Attempted to get sim-outorder working, so so...
00073  * Dependency fixes.
00074  *
00075  * Revision 1.1.2.15  2000/09/22 01:58:19  taustin
00076  * Finished UOP flow generation support.
00077  *
00078  * Revision 1.1.2.14  2000/09/19 17:25:38  taustin
00079  * Completed UOP decomposition code, all UOPs now take nominally one cycle on a
00080  * simple pipeline, including loads and stores.  Initial testing has the code
00081  * working fine, however, extensive random testing will occur when sim-fuzz.c
00082  * gets extended to support multiple functional units...
00083  *
00084  * Revision 1.1.2.13  2000/09/11 12:23:10  taustin
00085  * Added UOP decomposition routines, used by sim-uop, soon to used by perf
00086  * simulators.
00087  *
00088  * Revision 1.1.2.12  2000/09/05 13:56:34  taustin
00089  * Lots of fixes after simulating using the new SimpleScalar/ARM fuzz buster to
00090  * perform random co-simulation testing, very handy!
00091  *
00092  * Revision 1.1.2.11  2000/08/29 14:18:27  taustin
00093  * Fixed word and qword size fp register accesses.
00094  * Addes time() and times() system call support (for Perl).
00095  *
00096  * Revision 1.1.2.10  2000/08/26 06:54:11  taustin
00097  * Simplified SimpleScalar/ARM PC handling - seems to work...
00098  * More SimpleScalar/ARM instruction definition debug work.
00099  *
00100  * Revision 1.1.2.9  2000/08/22 18:38:54  taustin
00101  * More progress on the SimpleScalar/ARM target.
00102  *
00103  * Revision 1.1.2.8  2000/08/02 08:52:15  taustin
00104  * SimpleScalar/ARM co-simulation component, based on the ARMulator.
00105  * More fixes to the SimpleScalar/ARM target.
00106  *
00107  * Revision 1.1.2.7  2000/07/27 21:45:06  taustin
00108  * Added umpteen half word and signed byte loads.
00109  *
00110  * Revision 1.1.2.6  2000/07/27 19:12:09  omutlu
00111  * some fixes to cdp instruction. needs more work
00112  *
00113  * Revision 1.1.2.5  2000/07/26 05:01:52  taustin
00114  * More disassembler fixes...
00115  *
00116  * Revision 1.1.2.4  2000/07/25 18:29:06  omutlu
00117  * Modified the branch offset calculation, cmp, ldm
00118  *
00119  * Revision 1.1.2.3  2000/07/21 18:31:00  taustin
00120  * More progress on the SimpleScalar/ARM target.
00121  *
00122  * Revision 1.1.2.2  2000/07/13 03:09:56  taustin
00123  * More progress on the SimpleScalar/ARM target.
00124  *
00125  * Revision 1.1.2.1  2000/05/31 19:26:00  taustin
00126  * ARM definition files
00127  *
00128  * Revision 1.1.1.1  2000/05/26 15:22:27  taustin
00129  * SimpleScalar Tool Set
00130  *
00131  *
00132  * Revision 1.4  1999/12/31 18:58:15  taustin
00133  * quad_t naming conflicts removed
00134  * MD_FETCH_INST() macro fixed
00135  * Alpha instruction set extensions (MVI, BWX, AMASK, IMPLVER, etc...)
00136  *
00137  * Revision 1.3  1999/12/13 18:59:40  taustin
00138  * cross endian execution support added
00139  *
00140  * Revision 1.2  1998/08/31 17:15:23  taustin
00141  * fixed non-portable SEXT definitions
00142  *
00143  * Revision 1.1  1998/08/27 16:53:36  taustin
00144  * Initial revision
00145  *
00146  * Revision 1.1  1998/05/06  01:09:18  calder
00147  * Initial revision
00148  *
00149  * Revision 1.5  1997/03/11  01:38:10  taustin
00150  * updated copyrights
00151  * long/int tweaks made for ALPHA target support
00152  * IFAIL() hook now allows simulators to declare instruction faults
00153  * IDIV()/IMOD()/FDIV() hooks now support simulator fault masking
00154  * supported added for non-GNU C compilers
00155  *
00156  * Revision 1.4  1997/01/06  16:08:10  taustin
00157  * comments updated
00158  * functional unit definitions moved from ss.def
00159  *
00160  * Revision 1.3  1996/12/27  15:55:37  taustin
00161  * fixed system header collision with MAXINT
00162  *
00163  * Revision 1.1  1996/12/05  18:50:23  taustin
00164  * Initial revision
00165  *
00166  */
00167 
00168 #ifndef ARM_H
00169 #define ARM_H
00170 
00171 #include <stdio.h>
00172 
00173 #include "host.h"
00174 #include "misc.h"
00175 #include "config.h"
00176 #include "endian.h"
00177 
00178 
00179 /*
00180  * This file contains various definitions needed to decode, disassemble, and
00181  * execute ARM instructions.
00182  */
00183 
00184 /* build for ARM target */
00185 #define TARGET_ARM
00186 
00187 /* probe cross-endian execution */
00188 #if defined(BYTES_BIG_ENDIAN)
00189 #define MD_CROSS_ENDIAN
00190 #endif
00191 
00192 /* not applicable/available, usable in most definition contexts */
00193 #define NA              0
00194 
00195 /*
00196  * target-dependent type definitions
00197  */
00198 
00199 /* define MD_QWORD_ADDRS if the target requires 64-bit (qword) addresses */
00200 /* #define MD_QWORD_ADDRS */
00201 
00202 /* address type definition */
00203 typedef word_t md_addr_t;
00204 
00205 
00206 /*
00207  * target-dependent memory module configuration
00208  */
00209 
00210 /* physical memory page size (must be a power-of-two) */
00211 #define MD_PAGE_SIZE            4096
00212 #define MD_LOG_PAGE_SIZE        12
00213 
00214 
00215 /*
00216  * target-dependent instruction faults
00217  */
00218 
00219 enum md_fault_type {
00220   md_fault_none = 0,            /* no fault */
00221   md_fault_access,              /* storage access fault */
00222   md_fault_alignment,           /* storage alignment fault */
00223   md_fault_overflow,            /* signed arithmetic overflow fault */
00224   md_fault_div0,                /* division by zero fault */
00225   md_fault_invalid,             /* invalid arithmetic operation */ 
00226                                 /* added to allow SQRT{S,T} in FIX exts */
00227   md_fault_break,               /* BREAK instruction fault */
00228   md_fault_unimpl,              /* unimplemented instruction fault */
00229   md_fault_internal             /* internal S/W fault */
00230 };
00231 
00232 
00233 /*
00234  * target-dependent register file definitions, used by regs.[hc]
00235  */
00236 
00237 /* number of integer registers */
00238 #define MD_NUM_IREGS            (/* arch */16 + /* Ucode */16)
00239 
00240 /* number of floating point registers */
00241 #define MD_NUM_FREGS            8
00242 
00243 /* number of control registers */
00244 #define MD_NUM_CREGS            3
00245 
00246 /* total number of registers, excluding PC and NPC */
00247 #define MD_TOTAL_REGS                                                   \
00248   (/*int*/32 + /*fp*/8 + /*misc*/3 + /*tmp*/1 + /*mem*/1 + /*ctrl*/1)
00249 
00250 /* general purpose (integer) register file entry type */
00251 typedef word_t md_gpr_t[MD_NUM_IREGS];
00252 
00253 /* floating point register file entry type */
00254 typedef union {
00255   qword_t q[MD_NUM_FREGS];      /* integer qword view */
00256   dfloat_t d[MD_NUM_FREGS];     /* double-precision floating point view */
00257 } md_fpr_t;
00258 
00259 /* control register file contents */
00260 typedef struct {
00261   word_t cpsr;                  /* processor status register */
00262   word_t spsr;
00263   word_t fpsr;                  /* floating point status register */
00264 } md_ctrl_t;
00265 
00266 /* well known registers */
00267 enum md_reg_names {
00268   MD_REG_R0 = 0,
00269   MD_REG_V0 = 0,        /* return value reg */
00270   MD_REG_A0 = 0,        /* argument regs */
00271   MD_REG_R1 = 1,
00272   MD_REG_A1 = 1,
00273   MD_REG_R2 = 2,
00274   MD_REG_A2 = 2,
00275   MD_REG_R3 = 3,
00276   MD_REG_A3 = 3,
00277   MD_REG_R4 = 4,
00278   MD_REG_R5 = 5,
00279   MD_REG_R6 = 6,
00280   MD_REG_R7 = 7,
00281   MD_REG_R8 = 8,
00282   MD_REG_R9 = 9,
00283   MD_REG_R10 = 10,
00284   MD_REG_SL = 10,
00285   MD_REG_R11 = 11,
00286   MD_REG_FP = 11,       /* frame pointer */
00287   MD_REG_R12 = 12,
00288   MD_REG_IP = 12,
00289   MD_REG_R13 = 13,
00290   MD_REG_SP = 13,       /* stack pointer */
00291   MD_REG_R14 = 14,
00292   MD_REG_LR = 14,       /* link register */
00293   MD_REG_R15 = 15,
00294   MD_REG_PC = 15,       /* link register */
00295   MD_REG_TMP0 = 16,     /* temp registers - used by Ucode, 16 total */
00296   MD_REG_TMP1 = 17,
00297   MD_REG_TMP2 = 18,
00298   MD_REG_TMP3 = 19
00299 };
00300 
00301 /*
00302  * target-dependent instruction format definition
00303  */
00304 
00305 /* instruction formats */
00306 typedef word_t md_inst_t;
00307 
00308 /* preferred nop instruction definition */
00309 extern md_inst_t MD_NOP_INST;
00310 
00311 /* target swap support */
00312 #ifdef MD_CROSS_ENDIAN
00313 
00314 #define MD_SWAPH(X)             SWAP_HALF(X)
00315 #define MD_SWAPW(X)             SWAP_WORD(X)
00316 #define MD_SWAPQ(X)             SWAP_QWORD(X)
00317 #define MD_SWAPI(X)             SWAP_WORD(X)
00318 
00319 #else /* !MD_CROSS_ENDIAN */
00320 
00321 #define MD_SWAPH(X)             (X)
00322 #define MD_SWAPW(X)             (X)
00323 #define MD_SWAPQ(X)             (X)
00324 #define MD_SWAPD(X)             (X)
00325 #define MD_SWAPI(X)             (X)
00326 
00327 #endif
00328 
00329 /* fetch an instruction */
00330 #define MD_FETCH_INST(INST, MEM, PC)                                    \
00331   { (INST) = MEM_READ_WORD((MEM), (PC)); }
00332 
00333 /*
00334  * target-dependent loader module configuration
00335  */
00336 
00337 /* maximum size of argc+argv+envp environment */
00338 #define MD_MAX_ENVIRON          16384
00339 
00340 
00341 /*
00342  * machine.def specific definitions
00343  */
00344 
00345 /* inst -> enum md_opcode mapping, use this macro to decode insts */
00346 #define MD_TOP_OP(INST)         (((INST) >> 24) & 0x0f)
00347 #define MD_SET_OPCODE(OP, INST)                                         \
00348   { OP = md_mask2op[MD_TOP_OP(INST)];                                   \
00349     while (md_opmask[OP])                                               \
00350       OP = md_mask2op[((INST >> md_opshift[OP]) & md_opmask[OP])        \
00351                       + md_opoffset[OP]]; }
00352 
00353 /* largest opcode field value (currently upper 8-bit are used for pre/post-
00354     incr/decr operation specifiers */
00355 #define MD_MAX_MASK             2048
00356 
00357 /* global opcode names, these are returned by the decoder (MD_OP_ENUM()) */
00358 enum md_opcode {
00359   OP_NA = 0,    /* NA */
00360 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,O3,I1,I2,I3,I4) OP,
00361 #define DEFUOP(OP,NAME,OPFORM,RES,FLAGS,O1,O2,O3,I1,I2,I3,I4) OP,
00362 #define DEFLINK(OP,MSK,NAME,MASK,SHIFT) OP,
00363 #define CONNECT(OP)
00364 #include "machine.def"
00365   OP_MAX        /* number of opcodes + NA */
00366 };
00367 
00368 
00369 /* internal decoder state */
00370 extern enum md_opcode md_mask2op[];
00371 extern unsigned int md_opoffset[];
00372 extern unsigned int md_opmask[];
00373 extern unsigned int md_opshift[];
00374 
00375 
00376 /* enum md_opcode -> description string */
00377 #define MD_OP_NAME(OP)          (md_op2name[OP])
00378 extern char *md_op2name[];
00379 
00380 /* enum md_opcode -> opcode operand format, used by disassembler */
00381 #define MD_OP_FORMAT(OP)        (md_op2format[OP])
00382 extern char *md_op2format[];
00383 
00384 /* function unit classes, update md_fu2name if you update this definition */
00385 enum md_fu_class {
00386   FUClamd_NA = 0,       /* inst does not use a functional unit */
00387   IntALU,               /* integer ALU */
00388   IntMULT,              /* integer multiplier */
00389   IntDIV,               /* integer divider */
00390   FloatADD,             /* floating point adder/subtractor */
00391   FloatCMP,             /* floating point comparator */
00392   FloatCVT,             /* floating point<->integer converter */
00393   FloatMULT,            /* floating point multiplier */
00394   FloatDIV,             /* floating point divider */
00395   FloatSQRT,            /* floating point square root */
00396   RdPort,               /* memory read port */
00397   WrPort,               /* memory write port */
00398   NUM_FU_CLASSES        /* total functional unit classes */
00399 };
00400 
00401 /* enum md_opcode -> enum md_fu_class, used by performance simulators */
00402 #define MD_OP_FUCLASS(OP)       (md_op2fu[OP])
00403 extern enum md_fu_class md_op2fu[];
00404 
00405 /* enum md_fu_class -> description string */
00406 #define MD_FU_NAME(FU)          (md_fu2name[FU])
00407 extern char *md_fu2name[];
00408 
00409 /* instruction flags */
00410 #define F_ICOMP         0x00000001      /* integer computation */
00411 #define F_FCOMP         0x00000002      /* FP computation */
00412 #define F_CTRL          0x00000004      /* control inst */
00413 #define F_UNCOND        0x00000008      /*   unconditional change */
00414 #define F_COND          0x00000010      /*   conditional change */
00415 #define F_MEM           0x00000020      /* memory access inst */
00416 #define F_LOAD          0x00000040      /*   load inst */
00417 #define F_STORE         0x00000080      /*   store inst */
00418 #define F_DISP          0x00000100      /*   displaced (R+C) addr mode */
00419 #define F_RR            0x00000200      /*   R+R addr mode */
00420 #define F_DIRECT        0x00000400      /*   direct addressing mode */
00421 #define F_TRAP          0x00000800      /* traping inst */
00422 #define F_LONGLAT       0x00001000      /* long latency inst (for sched) */
00423 #define F_DIRJMP        0x00002000      /* direct jump */
00424 #define F_INDIRJMP      0x00004000      /* indirect jump */
00425 #define F_CALL          0x00008000      /* function call */
00426 #define F_FPCOND        0x00010000      /* FP conditional branch */
00427 #define F_IMM           0x00020000      /* instruction has immediate operand */
00428 #define F_CISC          0x00040000      /* CISC instruction */
00429 #define F_AGEN          0x00080000      /* AGEN micro-instruction */
00430 
00431 /* enum md_opcode -> opcode flags, used by simulators */
00432 #define MD_OP_FLAGS(OP)         (md_op2flags[OP])
00433 extern unsigned int md_op2flags[];
00434 
00435 
00436 /* integer register specifiers */
00437 #define RN              ((inst >> 16) & 0x0f)
00438 #define URN             ((inst >> 17) & 0x1f)   /* Ucode RN */
00439 #define RD              ((inst >> 12) & 0x0f)
00440 #define URD             ((inst >> 12) & 0x1f)   /* Ucode RD */
00441 #define RS              ((inst >> 8) & 0x0f)
00442 #define RM              (inst & 0x0f)
00443 
00444 /* floating point register specifiers */
00445 #define FN              ((inst >> 16) & 0x07)
00446 #define FD              ((inst >> 12) & 0x07)
00447 #define FM              (inst & 0x07)
00448 
00449 /* register shift accessors */
00450 #define SHIFT_BITS      ((inst >> 4) & 0xff)
00451 #define SHIFT_REG       ((inst >> 4) & 0x01)
00452 #define SHIFT_REG_PAD   ((inst >> 7) & 0x01)
00453 #define SHIFT_TYPE      ((inst >> 5) & 0x03)
00454 #define SHIFT_SHAMT     ((inst >> 7) & 0x1f)
00455 
00456 /* register shift types */
00457 #define SHIFT_LSL       0x00
00458 #define SHIFT_LSR       0x01
00459 #define SHIFT_ASR       0x02
00460 #define SHIFT_ROR       0x03
00461 
00462 /* rotated immediate accessors */
00463 #define ROTIMM          (inst & 0xff)
00464 #define ROTAMT          ((inst >> 8) & 0x0f)
00465 
00466 /* rotate operator */
00467 #define ROTR(VAL,N)                                                     \
00468   (((VAL) >> (int)((N) & 31)) | ((VAL) << (32 - (int)((N) & 31))))
00469 
00470 /* load/store 12-bit unsigned offset field value */
00471 #define OFS             ((word_t)(inst & 0xfff))
00472 
00473 /* load/store 8-bit unsigned offset field value */
00474 #define HOFS            ((word_t)((RS << 4) + RM))
00475 
00476 /* fp load/store 8-bit unsigned offset field value */
00477 #define FPOFS           ((word_t)((inst & 0xff) << 2))
00478 
00479 /* returns 24-bit signed immediate field value - made 2's complement - Onur 07/24/00 */
00480 #define BOFS                                                            \
00481   ((inst & 0x800000)                                                    \
00482    ? (0xfc000000 | ((inst & 0xffffff) << 2))                            \
00483    : ((inst & 0x7fffff) << 2))
00484 
00485 #if 0
00486 #define BOFS            ((((word_t)(inst & 0xffffff)) >> 23) ? ((word_t)(-67108864 + (word_t)(((inst & 0xffffff) << 2)))) : ((word_t)((inst & 0xffffff)) << 2))
00487 #endif
00488 
00489 /* coprocessor operation code for CDP instruction */
00490 #define CPOPC ((inst >> 20) & 0x0f)
00491 #define CPEXT ((inst >> 5) & 0x07)
00492 
00493 /* sign-extend operands */
00494 #define SEXT24(X)                                                       \
00495   (((X) & 0x800000) ? ((sword_t)(X) | 0xff800000)) : (sqword_t)(X))
00496 
00497 /* load/store opcode accessors */
00498 #define LDST_PU         ((inst >> 23) & 0x03)
00499 #define REGLIST         (inst & 0xffff)
00500 
00501 /* floating point opcode accessors */
00502 #define FPIMMBITS       (inst & 0x07)
00503 #define FPIMM           (md_fpimm[FPIMMBITS])
00504 extern double md_fpimm[8];
00505 
00506 #define EF_SIZE         (((inst >> 18) & 0x02) | ((inst >> 7) & 0x01))
00507 #define LDST_EF_SIZE    (((inst >> 21) & 0x02) | ((inst >> 15) & 0x01))
00508 #define GH_RNDMODE      ((inst >> 5) & 0x03)
00509 #define FCNT            (((inst >> 21) & 0x02) | ((inst >> 15) & 0x01))
00510 
00511 /* ones counter */
00512 #define ONES(EXPR)      (md_ones(EXPR))
00513 
00514 /* ones counter function */
00515 int md_ones(word_t val);
00516 
00517 /* arithmetic flags */
00518 #define ADDC(LHS, RHS, RES)             md_addc((LHS), (RHS), (RES))
00519 #define ADDV(LHS, RHS, RES)             md_addv((LHS), (RHS), (RES))
00520 #define SUBC(LHS, RHS, RES)             md_subc((LHS), (RHS), (RES))
00521 #define SUBV(LHS, RHS, RES)             md_subv((LHS), (RHS), (RES))
00522 
00523 int md_addc(word_t lhs, word_t rhs, word_t res);
00524 int md_addv(word_t lhs, word_t rhs, word_t res);
00525 int md_subc(word_t lhs, word_t rhs, word_t res);
00526 int md_subv(word_t lhs, word_t rhs, word_t res);
00527 
00528 /* SWI accessors */
00529 #define SYSCODE         (inst & 0xffffff)
00530 
00531 /* default target PC handling */
00532 #ifndef SET_TPC
00533 #define SET_TPC(PC)     (void)0
00534 #endif /* SET_TPC */
00535 
00536 /* processor status register accessors */
00537 #define _PSR_N(PSR)             (((PSR) >> 31) & 1)
00538 #define _SET_PSR_N(PSR, VAL)                                            \
00539   ((PSR) = (((PSR) & ~(1 << 31)) | (((VAL) & 1) << 31)))
00540 #define _PSR_Z(PSR)             (((PSR) >> 30) & 1)
00541 #define _SET_PSR_Z(PSR, VAL)                                            \
00542   ((PSR) = (((PSR) & ~(1 << 30)) | (((VAL) & 1) << 30)))
00543 #define _PSR_C(PSR)             (((PSR) >> 29) & 1)
00544 #define _SET_PSR_C(PSR, VAL)                                            \
00545   ((PSR) = (((PSR) & ~(1 << 29)) | (((VAL) & 1) << 29)))
00546 #define _PSR_V(PSR)             (((PSR) >> 28) & 1)
00547 #define _SET_PSR_V(PSR, VAL)                                            \
00548   ((PSR) = (((PSR) & ~(1 << 28)) | (((VAL) & 1) << 28)))
00549 
00550 #define _PSR_IRQ(PSR)           (((PSR) >> 7) & 1)
00551 #define _PSR_FIQ(PSR)           (((PSR) >> 6) & 1)
00552 #define _PSR_MODE(PSR)          ((PSR) & 0x1f)
00553 
00554 /* condition code values */
00555 #define COND_EQ         0x00
00556 #define COND_NE         0x01
00557 #define COND_CS         0x02
00558 #define COND_CC         0x03
00559 #define COND_MI         0x04
00560 #define COND_PL         0x05
00561 #define COND_VS         0x06
00562 #define COND_VC         0x07
00563 #define COND_HI         0x08
00564 #define COND_LS         0x09
00565 #define COND_GE         0x0a
00566 #define COND_LT         0x0b
00567 #define COND_GT         0x0c
00568 #define COND_LE         0x0d
00569 #define COND_AL         0x0e
00570 #define COND_NV         0x0f
00571 
00572 /* condition opcode accessor */
00573 #define COND            ((inst >> 28) & 0x0f)
00574 
00575 /* test instruction condition value */
00576 #define COND_VALID(PSR) (((COND) == COND_AL) || md_cond_ok(inst, PSR))
00577 
00578 /* full capability instruction condition evaluator */
00579 extern int md_cond_ok(md_inst_t inst, word_t psr);
00580 
00581 /* compute shifted register RM value */
00582 #define SHIFTRM(RMVAL, RSVAL, CFVAL)                                    \
00583   (((SHIFT_BITS)==0) ? (RMVAL) : md_shiftrm(inst, (RMVAL), (RSVAL), (CFVAL)))
00584 
00585 /* full capability shifted register RM routine */
00586 extern word_t
00587 md_shiftrm(md_inst_t inst, word_t rmval, word_t rs_val, word_t psr);
00588 
00589 #define SHIFTC(RMVAL, RSVAL, CFVAL)                                     \
00590   (((SHIFT_BITS)==0) ? (CFVAL) : md_shiftc(inst, (RMVAL), (RSVAL), (CFVAL)))
00591 
00592 /* full capability shifted register CF routine */
00593 word_t
00594 md_shiftc(md_inst_t inst, word_t rmval, word_t rsval, word_t cfval);
00595 
00596 /*
00597  * various other helper macros/functions
00598  */
00599 
00600 /* non-zero if system call is an exit() */
00601 #define OSF_SYS_exit                    1
00602 #define MD_EXIT_SYSCALL(REGS)                                           \
00603   ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_exit)
00604 
00605 /* non-zero if system call is a write to stdout/stderr */
00606 #define OSF_SYS_write                   4
00607 #define MD_OUTPUT_SYSCALL(REGS)                                         \
00608   ((REGS)->regs_R[MD_REG_V0] == OSF_SYS_write                           \
00609    && ((REGS)->regs_R[MD_REG_A0] == /* stdout */1                       \
00610        || (REGS)->regs_R[MD_REG_A0] == /* stderr */2))
00611 
00612 /* returns stream of an output system call, translated to host */
00613 #define MD_STREAM_FILENO(REGS)          ((REGS)->regs_R[MD_REG_A0])
00614 
00615 /* returns non-zero if instruction is a function call */
00616 #define MD_IS_CALL(OP)                  ((OP) == BRL)
00617 
00618 /* returns non-zero if instruction is a function return */
00619 /* FIXME: this will never return TRUE */
00620 #define MD_IS_RETURN(OP)                ((OP) == MOV)
00621 
00622 /* returns non-zero if instruction is an indirect jump */
00623 /* FIXME: !!! */
00624 #define MD_IS_INDIR(OP)                 ((OP) == MOV)
00625 
00626 /* addressing mode probe, enums and strings */
00627 enum md_amode_type {
00628   md_amode_imm,         /* immediate addressing mode */
00629   md_amode_gp,          /* global data access through global pointer */
00630   md_amode_sp,          /* stack access through stack pointer */
00631   md_amode_fp,          /* stack access through frame pointer */
00632   md_amode_disp,        /* (reg + const) addressing */
00633   md_amode_rr,          /* (reg + reg) addressing */
00634   md_amode_NUM
00635 };
00636 extern char *md_amode_str[md_amode_NUM];
00637 
00638 /* addressing mode pre-probe FSM, must see all instructions */
00639 #define MD_AMODE_PREPROBE(OP, FSM)              { (FSM) = 0; }
00640 
00641 /* compute addressing mode, only for loads/stores */
00642 #define MD_AMODE_PROBE(AM, OP, FSM)                                     \
00643   {                                                                     \
00644     if (MD_OP_FLAGS(OP) & F_DISP)                                       \
00645       {                                                                 \
00646         if ((RB) == MD_REG_GP)                                          \
00647           (AM) = md_amode_gp;                                           \
00648         else if ((RB) == MD_REG_SP)                                     \
00649           (AM) = md_amode_sp;                                           \
00650         else if ((RB) == MD_REG_FP) /* && bind_to_seg(addr) == seg_stack */\
00651           (AM) = md_amode_fp;                                           \
00652         else                                                            \
00653           (AM) = md_amode_disp;                                         \
00654       }                                                                 \
00655     else if (MD_OP_FLAGS(OP) & F_RR)                                    \
00656       (AM) = md_amode_rr;                                               \
00657     else                                                                \
00658       panic("cannot decode addressing mode");                           \
00659   }
00660 
00661 /* addressing mode pre-probe FSM, after all loads and stores */
00662 #define MD_AMODE_POSTPROBE(FSM)                 /* nada... */
00663 
00664 
00665 /*
00666  * EIO package configuration/macros
00667  */
00668 
00669 /* expected EIO file format */
00670 #define MD_EIO_FILE_FORMAT              EIO_ALPHA_FORMAT
00671 
00672 #define MD_MISC_REGS_TO_EXO(REGS)                                       \
00673   exo_new(ec_list,                                                      \
00674           /*icnt*/exo_new(ec_integer, (exo_integer_t)sim_num_insn),     \
00675           /*PC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_PC),    \
00676           /*NPC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_NPC),  \
00677           NULL)
00678 
00679 #if XXX
00680           /*FPCR*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fpcr),
00681           /*UNIQ*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.uniq),
00682 #endif
00683 
00684 #define MD_IREG_TO_EXO(REGS, IDX)                                       \
00685   exo_new(ec_address, (exo_integer_t)(REGS)->regs_R[IDX])
00686 
00687 #define MD_FREG_TO_EXO(REGS, IDX)                                       \
00688   exo_new(ec_address, (exo_integer_t)(REGS)->regs_F.q[IDX])
00689 
00690 #define MD_EXO_TO_MISC_REGS(EXO, ICNT, REGS)                            \
00691   /* check EXO format for errors... */                                  \
00692   if (!exo                                                              \
00693       || exo->ec != ec_list                                             \
00694       || !exo->as_list.head                                             \
00695       || exo->as_list.head->ec != ec_integer                            \
00696       || !exo->as_list.head->next                                       \
00697       || exo->as_list.head->next->ec != ec_address                      \
00698       || !exo->as_list.head->next->next                                 \
00699       || exo->as_list.head->next->next->ec != ec_address                \
00700       || !exo->as_list.head->next->next->next                           \
00701       || exo->as_list.head->next->next->next->ec != ec_integer          \
00702       || !exo->as_list.head->next->next->next->next                     \
00703       || exo->as_list.head->next->next->next->next->ec != ec_integer    \
00704       || exo->as_list.head->next->next->next->next->next != NULL)       \
00705     fatal("could not read EIO misc regs");                              \
00706   (ICNT) = (counter_t)exo->as_list.head->as_integer.val;                \
00707   (REGS)->regs_PC = (md_addr_t)exo->as_list.head->next->as_integer.val; \
00708   (REGS)->regs_NPC =                                                    \
00709     (md_addr_t)exo->as_list.head->next->next->as_integer.val;
00710 
00711 #if XXX
00712   (REGS)->regs_C.fpcr =
00713     (qword_t)exo->as_list.head->next->next->next->as_integer.val;
00714   (REGS)->regs_C.uniq =
00715     (qword_t)exo->as_list.head->next->next->next->next->as_integer.val;
00716 #endif
00717 
00718 #define MD_EXO_TO_IREG(EXO, REGS, IDX)                                  \
00719   ((REGS)->regs_R[IDX] = (qword_t)(EXO)->as_integer.val)
00720 
00721 #define MD_EXO_TO_FREG(EXO, REGS, IDX)                                  \
00722   ((REGS)->regs_F.q[IDX] = (qword_t)(EXO)->as_integer.val)
00723 
00724 #define MD_EXO_CMP_IREG(EXO, REGS, IDX)                                 \
00725   ((REGS)->regs_R[IDX] != (qword_t)(EXO)->as_integer.val)
00726 
00727 #define MD_FIRST_IN_REG                 0
00728 #define MD_LAST_IN_REG                  21
00729 
00730 #define MD_FIRST_OUT_REG                0
00731 #define MD_LAST_OUT_REG                 21
00732 
00733 
00734 /*
00735  * configure the EXO package
00736  */
00737 
00738 /* EXO pointer class */
00739 typedef qword_t exo_address_t;
00740 
00741 /* EXO integer class, 64-bit encoding */
00742 typedef qword_t exo_integer_t;
00743 
00744 /* EXO floating point class, 64-bit encoding */
00745 typedef double exo_float_t;
00746 
00747 
00748 /*
00749  * configure the stats package
00750  */
00751 
00752 /* counter stats */
00753 #define stat_reg_counter                stat_reg_sqword
00754 #define sc_counter                      sc_sqword
00755 #define for_counter                     for_sqword
00756 
00757 /* address stats */
00758 #define stat_reg_addr                   stat_reg_uint
00759 
00760 
00761 /*
00762  * configure the DLite! debugger
00763  */
00764 
00765 /* register bank specifier */
00766 enum md_reg_type {
00767   rt_gpr,               /* general purpose register */
00768   rt_lpr,               /* integer-precision floating pointer register */
00769   rt_fpr,               /* single-precision floating pointer register */
00770   rt_dpr,               /* double-precision floating pointer register */
00771   rt_ctrl,              /* control register */
00772   rt_PC,                /* program counter */
00773   rt_NPC,               /* next program counter */
00774   rt_NUM
00775 };
00776 
00777 /* register name specifier */
00778 struct md_reg_names_t {
00779   char *str;                    /* register name */
00780   enum md_reg_type file;        /* register file */
00781   int reg;                      /* register index */
00782 };
00783 
00784 /* symbolic register names, parser is case-insensitive */
00785 extern struct md_reg_names_t md_reg_names[];
00786 
00787 /* returns a register name string */
00788 char *md_reg_name(enum md_reg_type rt, int reg);
00789 
00790 /* default register accessor object */
00791 struct eval_value_t;
00792 struct regs_t;
00793 char *                                          /* err str, NULL for no err */
00794 md_reg_obj(struct regs_t *regs,                 /* registers to access */
00795            int is_write,                        /* access type */
00796            enum md_reg_type rt,                 /* reg bank to probe */
00797            int reg,                             /* register number */
00798            struct eval_value_t *val);           /* input, output */
00799 
00800 /* print integer REG(S) to STREAM */
00801 void md_print_ireg(md_gpr_t regs, int reg, FILE *stream);
00802 void md_print_iregs(md_gpr_t regs, FILE *stream);
00803 
00804 /* print floating point REG(S) to STREAM */
00805 void md_print_fpreg(md_fpr_t regs, int reg, FILE *stream);
00806 void md_print_fpregs(md_fpr_t regs, FILE *stream);
00807 
00808 /* print control REG(S) to STREAM */
00809 void md_print_creg(md_ctrl_t regs, int reg, FILE *stream);
00810 void md_print_cregs(md_ctrl_t regs, FILE *stream);
00811 
00812 /* xor checksum registers */
00813 word_t md_xor_regs(struct regs_t *regs);
00814 
00815 
00816 /*
00817  * configure sim-outorder specifics
00818  */
00819 
00820 /* primitive operation used to compute addresses within pipeline */
00821 #define MD_AGEN_OP              ADDQ
00822 
00823 /* NOP operation when injected into the pipeline */
00824 #define MD_NOP_OP               OP_NA
00825 
00826 /* non-zero for a valid address, used to determine if speculative accesses
00827    should access the DL1 data cache */
00828 #define MD_VALID_ADDR(ADDR)                                             \
00829   (((ADDR) >= ld_text_base && (ADDR) < (ld_text_base + ld_text_size))   \
00830    || ((ADDR) >= ld_data_base && (ADDR) < ld_brk_point)                 \
00831    || ((ADDR) >= (ld_stack_base - 16*1024*1024) && (ADDR) < ld_stack_base))
00832 
00833 /*
00834  * configure branch predictors
00835  */
00836 
00837 /* shift used to ignore branch address least significant bits, usually
00838    log2(sizeof(md_inst_t)) */
00839 #define MD_BR_SHIFT             2       /* log2(4) */
00840 
00841 
00842 /*
00843  * target-dependent routines
00844  */
00845 
00846 /* intialize the inst decoder, this function builds the ISA decode tables */
00847 void md_init_decoder(void);
00848 
00849 /* ARM UOP definition */
00850 #define MD_MAX_FLOWLEN          64
00851 struct md_uop_t {
00852   enum md_opcode op;            /* decoded opcode of the UOP */
00853   md_inst_t inst;               /* instruction bits of UOP */
00854 };
00855 
00856 /* UOP flow generator, returns a small non-cyclic program implementing OP,
00857    returns length of flow returned */
00858 int
00859 md_get_flow(enum md_opcode op, md_inst_t inst,
00860             struct md_uop_t flow[MD_MAX_FLOWLEN]);
00861 
00862 /* disassemble a SimpleScalar instruction */
00863 void
00864 md_print_insn(md_inst_t inst,           /* instruction to disassemble */
00865               md_addr_t pc,             /* addr of inst, used for PC-rels */
00866               FILE *stream);            /* output stream */
00867 
00868 /* disassemble an Alpha instruction */
00869 void
00870 md_print_uop(enum md_opcode op,
00871              md_inst_t inst,            /* instruction to disassemble */
00872              md_addr_t pc,              /* addr of inst, used for PC-rels */
00873              FILE *stream);             /* output stream */
00874 
00875 #endif /* ARM_H */

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