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

sst/elements/genericProc/FE/ppcFrontEnd/ppcMachine.h

00001 /* * powerpc.h - PowerPC definitions
00002  *
00003  * This file is a part of the SimpleScalar tool suite written by
00004  * Todd M. Austin as a part of the Multiscalar Research Project.
00005  *  
00006  * The tool suite is currently maintained by Doug Burger and Todd M. Austin.
00007  * 
00008  * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin
00009  *
00010  * This source file is distributed "as is" in the hope that it will be
00011  * useful.  The tool set comes with no warranty, and no author or
00012  * distributor accepts any responsibility for the consequences of its
00013  * use. 
00014  * 
00015  * Everyone is granted permission to copy, modify and redistribute
00016  * this tool set under the following conditions:
00017  * 
00018  *    This source code is distributed for non-commercial use only. 
00019  *    Please contact the maintainer for restrictions applying to 
00020  *    commercial use.
00021  *
00022  *    Permission is granted to anyone to make or distribute copies
00023  *    of this source code, either as received or modified, in any
00024  *    medium, provided that all copyright notices, permission and
00025  *    nonwarranty notices are preserved, and that the distributor
00026  *    grants the recipient permission for further redistribution as
00027  *    permitted by this document.
00028  *
00029  *    Permission is granted to distribute this file in compiled
00030  *    or executable form under the same conditions that apply for
00031  *    source code, provided that either:
00032  *
00033  *    A. it is accompanied by the corresponding machine-readable
00034  *       source code,
00035  *    B. it is accompanied by a written offer, with no time limit,
00036  *       to give anyone a machine-readable copy of the corresponding
00037  *       source code in return for reimbursement of the cost of
00038  *       distribution.  This written offer must permit verbatim
00039  *       duplication by anyone, or
00040  *    C. it is distributed by someone who received only the
00041  *       executable form, and is accompanied by a copy of the
00042  *       written offer of source code that they received concurrently.
00043  *
00044  * In other words, you are welcome to use, share and improve this
00045  * source file.  You are forbidden to forbid anyone else to use, share
00046  * and improve what you give them.
00047  *
00048  * INTERNET: dburger@cs.wisc.edu
00049  * US Mail:  1210 W. Dayton Street, Madison, WI 53706
00050  *
00051  *
00052  *
00053  */
00054 
00055 #ifndef PPC_H
00056 #define PPC_H
00057 
00058 #include <stdio.h>
00059 
00060 #include "fuClasses.h"
00061 #include "global.h"
00062 #include "host.h"
00063 #include "misc.h"
00064 #include "ieee-fp.h"
00065 //#include "sst/boost.h"
00066 
00067 /* Macros and such for softFloat */
00068 #include "softfloat/softfloat.h"
00069 #include "softfloat/softfloat_macros.h"
00070 
00071 /* #include "ppcmacros.h" */
00072 /* inline the file ppcmacros.h instead to stick with simplescalar distribution
00073 semantics */
00074 
00075 /* ppcmacros.h begin */ 
00076 /*
00077  *Registers are numbered in the following way:
00078  *  0 - 31 Integer registers
00079  * 32 - 63 Floating point registers
00080  * 64 - CR
00081  * 65 - FPSCR
00082  * 66 - XER
00083  * 67 - LR
00084  * 68 - CNTR
00085  * 70 - used by ssbackend
00086  * 70 - 102 Vector
00087  * 104 - used by WACI
00088  * 106 - used by WACI Store
00089  */
00090 
00091 /*GPR and SET_GPR are not defined here since they are defined correctly in sim-fast/sim-outroder correctly and are not included in any ifdef(TARGET_*)*/
00092 
00093 // turn on FP conversion instr
00094 #define FP_ROUND_CONVERSION_INST
00095 
00096 #define PPC_DFPR_DW(N)    PPC_DFPR(N)
00097 
00098 #define PPC_DXER_LR_CNTR(N)       ( (N==1)? PPC_DXER :((N==8)? PPC_DLR : PPC_DCNTR) )
00099 
00100 /*Macros which help in the reading of the registers are defined here*/
00101 
00102 #define PPC_GET_XER_CA            ((XER>>29)&0x1)
00103 #define PPC_GET_XER_SO            ((XER>>31)&0x1)
00104 #define PPC_GET_FPSCR_VE          ((FPSCR>>7)&0x1)
00105 
00106 /*FIXME: Speculative mode for these registers have to be defined*/
00107 #define LR     ntohl(regs.regs_L)
00108 #define CNTR   ntohl(regs.regs_CNTR)
00109 #define TBR    ntohl(regs.regs_TBR)
00110 
00111 
00112 #define CR            ntohl(regs.regs_C.cr)
00113 #define XER           ntohl(regs.regs_C.xer)
00114 #define FPSCR         ntohl(regs.regs_C.fpscr)
00115 
00116 /*Read the lower 32 bits of the floating foint register N*/
00117 
00118 //#define PPC_FPR_W(N)   ((word_t)((*(qword_t*)(&(PPC_FPR(N))))&0xffffffff))
00119 word_t readLower(const qword_t d);
00120 word_t readUpper(const qword_t d);
00121 qword_t readWhole(const double d);
00122 
00123 //#define PPC_FPR_W(N)     (readLower(PPC_FPR(N)))
00124 #define PPC_FPR_W(N)     (readLower(endian_swap(readWhole((FPReg[(N)])))))
00125 
00126 /*Read the upper 32 bits of the floating foint register N*/
00127 
00128 //#define PPC_FPR_UW(N)     ((word_t)( (*(qword_t*)(&(PPC_FPR(N)))>>32 )&0xffffffff))
00129 #define PPC_FPR_UW(N)     (readUpper(endian_swap(readWhole((FPReg[(N)])))))
00130 
00131 /*Read the floating foint register N as 64 bits*/
00132 #define PPC_FPR_DW(N)     (endian_swap(readWhole(FPReg[(N)])))
00133 
00134 
00135 /*Macros which help in the writing the registers are defined here*/
00136 
00137 
00138 /***These have to be defined for the speculative mode as well*/
00139 #define PPC_SET_LR(EXPR)                ((regs.regs_L = htonl(EXPR)))
00140 
00141 #define PPC_SET_CNTR(EXPR)              ((regs.regs_CNTR = htonl(EXPR)))
00142 
00143 
00144 
00145 #define PPC_SET_CR(EXPR)         (regs.regs_C.cr = htonl(EXPR))
00146 
00147 #define PPC_SET_XER(EXPR)        (regs.regs_C.xer = htonl(EXPR))
00148 
00149 
00150 #define PPC_SET_XER_SO           (regs.regs_C.xer = htonl((XER)|0x80000000))
00151 
00152 #define PPC_RESET_XER_SO         (regs.regs_C.xer = htonl((XER)&0x7fffffff))
00153 
00154 #define PPC_SET_XER_CA           (regs.regs_C.xer = htonl((XER)|0x20000000))
00155 
00156 #define PPC_RESET_XER_CA         (regs.regs_C.xer = htonl((XER)&0xdfffffff))
00157 
00158 
00159 #define PPC_SET_XER_OV          (regs.regs_C.xer = htonl((XER)|0x40000000))
00160 
00161 #define PPC_RESET_XER_OV        (regs.regs_C.xer = htonl((XER)&0xbfffffff))
00162 
00163 
00164 
00165 #define PPC_SET_FPSCR(EXPR)     (regs.regs_C.fpscr = htonl(EXPR))
00166 
00167 
00168 #define PPC_SET_FPSCR_FX        (regs.regs_C.fpscr =  htonl((FPSCR)|0x80000000))
00169 
00170 #define PPC_RESET_FPSCR_FX      (regs.regs_C.fpscr = htonl((FPSCR)&0x7fffffff))
00171 
00172 #define PPC_SET_FPSCR_FEX       (regs.regs_C.fpscr = htonl((FPSCR)|0x40000000))
00173 
00174 #define PPC_RESET_FPSCR_FEX     (regs.regs_C.fpscr = htonl((FPSCR)&0xbfffffff))
00175 
00176 #define PPC_SET_FPSCR_VX        (regs.regs_C.fpscr = htonl((FPSCR)|0x20000000))
00177 
00178 #define PPC_RESET_FPSCR_VX      (regs.regs_C.fpscr = htonl((FPSCR)&0xdfffffff))
00179 
00180 #define PPC_SET_FPSCR_OX        (regs.regs_C.fpscr = htonl((FPSCR)|0x10000000))
00181 
00182 #define PPC_RESET_FPSCR_OX      (regs.regs_C.fpscr = htonl((FPSCR)&0xefffffff))
00183 
00184 #define PPC_SET_FPSCR_UX        (regs.regs_C.fpscr = htonl((FPSCR)|0x08000000))
00185 
00186 #define PPC_RESET_FPSCR_UX      (regs.regs_C.fpscr = htonl((FPSCR)&0xf7ffffff))
00187 
00188 #define PPC_SET_FPSCR_ZX        (regs.regs_C.fpscr = htonl((FPSCR)|0x04000000))
00189 
00190 #define PPC_RESET_FPSCR_ZX      (regs.regs_C.fpscr = htonl((FPSCR)&0xfbffffff))
00191 
00192 #define PPC_SET_FPSCR_XX        (regs.regs_C.fpscr = htonl((FPSCR)|0x02000000))
00193 
00194 #define PPC_RESET_FPSCR_XX      (regs.regs_C.fpscr = htonl((FPSCR)&0xfdffffff))
00195 
00196 #define PPC_SET_FPSCR_VXSNAN    (regs.regs_C.fpscr = htonl((FPSCR)|0x01000000))
00197 
00198 #define PPC_RESET_FPSCR_VXSNAN  (regs.regs_C.fpscr = htonl((FPSCR)&0xfeffffff))
00199 
00200 #define PPC_SET_FPSCR_VXISI     (regs.regs_C.fpscr = htonl((FPSCR)|0x00800000))
00201 
00202 #define PPC_RESET_FPSCR_VXISI   (regs.regs_C.fpscr = htonl((FPSCR)&0xff7fffff))
00203 
00204 #define PPC_SET_FPSCR_VXIDI     (regs.regs_C.fpscr = htonl((FPSCR)|0x00400000))
00205 
00206 #define PPC_RESET_FPSCR_VXIDI   (regs.regs_C.fpscr = htonl((FPSCR)&0xffbfffff))
00207 
00208 #define PPC_SET_FPSCR_VXZDZ     (regs.regs_C.fpscr = htonl((FPSCR)|0x00200000))
00209 
00210 #define PPC_RESET_FPSCR_VXZDZ   (regs.regs_C.fpscr = htonl((FPSCR)&0xffdfffff))
00211 
00212 #define PPC_SET_FPSCR_VXIMZ     (regs.regs_C.fpscr = htonl((FPSCR)|0x00100000))
00213 
00214 #define PPC_RESET_FPSCR_VXIMZ   (regs.regs_C.fpscr = htonl((FPSCR)&0xffefffff))
00215 
00216 #define PPC_SET_FPSCR_VXVC      (regs.regs_C.fpscr = htonl((FPSCR)|0x00080000))
00217 
00218 #define PPC_RESET_FPSCR_VXVC    (regs.regs_C.fpscr = htonl((FPSCR)&0xfff7ffff))
00219 
00220 #define PPC_SET_FPSCR_VXSOFT    (regs.regs_C.fpscr = htonl((FPSCR)|0x00000400))
00221 
00222 #define PPC_RESET_FPSCR_VXSOFT  (regs.regs_C.fpscr = htonl((FPSCR)&0xfffffbff))
00223 
00224 #define PPC_SET_FPSCR_VXSQRT    (regs.regs_C.fpscr = htonl((FPSCR)|0x00000200))
00225 
00226 #define PPC_RESET_FPSCR_VXSQRT  (regs.regs_C.fpscr = htonl((FPSCR)&0xfffffdff))
00227 
00228 #define PPC_SET_FPSCR_VXCVI     (regs.regs_C.fpscr = htonl((FPSCR)|0x00000100))
00229 
00230 #define PPC_RESET_FPSCR_VXCVI   (regs.regs_C.fpscr= htonl((FPSCR)&0xfffffeff))
00231 
00232 #define PPC_SET_FPSCR_FPCC(EXPR)  (regs.regs_C.fpscr = htonl(((FPSCR)&0xffff0fff)|(((EXPR)&0xf)<<12)))
00233 
00234 #define PPC_SET_FPSCR_FPRF(EXPR) (regs.regs_C.fpscr = htonl(((FPSCR)&0xfffe0fff)|(((EXPR)&0x1f)<<12)))
00235 
00236 #define PPC_SET_CR0_LT          (regs.regs_C.cr = htonl((CR)|0x80000000))
00237 
00238 #define PPC_RESET_CR0_LT        (regs.regs_C.cr = htonl((CR)&0x7fffffff))
00239 
00240 #define PPC_SET_CR1_FX          (regs.regs_C.cr = htonl((CR)|0x08000000))
00241 
00242 #define PPC_RESET_CR1_FX        (regs.regs_C.cr = htonl((CR)&0xf7ffffff))
00243 
00244 #define PPC_SET_CR0_GT          (regs.regs_C.cr = htonl((CR)|0x40000000))
00245 
00246 #define PPC_RESET_CR0_GT        (regs.regs_C.cr = htonl((CR)&0xbfffffff))
00247 
00248 #define PPC_SET_CR1_FEX         (regs.regs_C.cr = htonl((CR)|0x04000000))
00249 
00250 #define PPC_RESET_CR1_FEX       (regs.regs_C.cr = htonl((CR)&0xfbffffff))
00251 
00252 #define PPC_SET_CR0_EQ          (regs.regs_C.cr = htonl((CR)|0x20000000))
00253 
00254 #define PPC_RESET_CR0_EQ        (regs.regs_C.cr = htonl((CR)&0xdfffffff))
00255 
00256 #define PPC_SET_CR1_VX          (regs.regs_C.cr = htonl((CR)|0x02000000))
00257 
00258 #define PPC_RESET_CR1_VX        (regs.regs_C.cr = htonl((CR)&0xfdffffff))
00259 
00260 #define PPC_SET_CR0_SO          (regs.regs_C.cr = htonl((CR)|0x10000000))
00261 
00262 #define PPC_RESET_CR0_SO        (regs.regs_C.cr = htonl((CR)&0xefffffff))
00263 
00264 #define PPC_SET_CR1_OX          (regs.regs_C.cr = htonl((CR)|0x01000000))
00265 
00266 #define PPC_RESET_CR1_OX        (regs.regs_C.cr = htonl((CR)&0xfeffffff))
00267 
00268 #define PPC_CLEAR_CR6           (regs.regs_C.cr = htonl((CR)&0xffffff0f))
00269 #define PPC_SET_CR6(xxx)        (regs.regs_C.cr = htonl((CR)|(xxx<<4)))
00270 
00271 
00272 
00273 
00274 
00275 /*Write floating-point reg N as double word. This macro assumes that the expression passed is a quad */
00276 
00277 #define PPC_SET_FPR_DW(N,EXPR)    (regs.regs_F.d[(N)] = convertDWToDouble((EXPR)))
00278 
00279 
00280 #define PPC_SET_FPR_D(N,EXPR)    (regs.regs_F.d[(N)] = (EXPR))
00281 
00282 
00283 
00284 
00285 
00286 /*These macros are for Cache management instructions*/
00287 
00288 /*Data cache block flush, invalidates the block in the cache addressed by EA*/
00289 
00290 #define EXEC_DCBF(EA)
00291 
00292 /*Data cache block invalidate */
00293 #define EXEC_DCBI(EA)
00294 
00295 /*Data cache block store*/
00296 
00297 #define EXEC_DCBST(EA)
00298 
00299 /*Data cache block touch*/
00300 
00301 #define EXEC_DCBT(EA)
00302 
00303 /*Data cache block touch for store*/
00304 
00305 #define EXEC_DCBTST(EA)
00306 
00307 /*Data cache block clear to zero*/
00308 
00309 #define EXEC_DCBZ(EA)
00310 
00311 /*Instruction cache block invalidate*/
00312 
00313 #define EXEC_ICBI(EA)                   
00314 
00315 /*Memory Synchronization instructions*/
00316 
00317 #define EXEC_ISYNC                      
00318 #define EXEC_SYNC                       
00319 #define EXEC_EIEIO                      
00320 
00321 /*Returns the word at the address EA*/
00322 
00323 #define EXEC_LWARX(EA,FAULT)            
00324 
00325 /*Stores the word and returns CR0*/
00326 
00327 #define EXEC_STWCXD(WORD,EA,FAULT,CR0)  
00328 
00329 
00330 /*These macros are for the Trap handler invocation*/
00331 
00332 /*Call system trap handler*/
00333 
00334 #define PPC_TRAP (void)0;       
00335 /*External control instructions*/
00336 
00337 /*Returns the word at the address EA*/
00338 
00339 #define EXEC_ECIWX(EA,FAULT)            
00340 
00341 /*Stores the word at EA*/
00342 
00343 #define EXEC_ECOWX(WORD,EA,FAULT)       
00344 
00345 #define PPC_SYSCALL                     
00346 
00347 /* ppcmacros.h ends */
00348 
00349 /*
00350  * This file contains various definitions needed to decode, disassemble, and
00351  * execute PowerPC instructions.
00352  */
00353 
00354 /* build for PowerPC target */
00355 #define TARGET_PPC 
00356 
00357 /* not applicable/available, usable in most definition contexts */
00358 #define NA              0
00359 
00360 /*
00361  * target-dependent type definitions
00362  */
00363 
00364 /* define MD_QWORD_ADDRS if the target requires 64-bit (quadword) addresses */
00365 #undef MD_QWORD_ADDRS
00366 
00367 /* address type definition */
00368 typedef word_t md_addr_t;
00369 
00370 
00371 /*
00372  * target-dependent memory module configuration
00373  */
00374 
00375 /* physical memory page size (must be a power-of-two) */
00376 #define MD_PAGE_SIZE            4096
00377 /*Base 2 Logarithm of the physical memory page size*/
00378 #define MD_LOG_PAGE_SIZE        12
00379 
00380 
00381 /*
00382  * target-dependent instruction faults
00383  */
00384 
00385 enum md_fault_type {
00386   md_fault_none = 0,            /* no fault */
00387   md_fault_access,              /* storage access fault */
00388   md_fault_alignment,           /* storage alignment fault */
00389   md_fault_overflow,            /* signed arithmetic overflow fault */
00390   md_fault_div0,                /* division by zero fault */
00391   md_fault_break,               /* BREAK instruction fault */
00392   md_fault_unimpl,              /* unimplemented instruction fault */
00393   md_fault_invalidinstruction,  /* PowerPC has an invalid instruction fault */
00394   md_fault_internal             /* internal S/W fault */
00395 };
00396 
00397 
00398 /*
00399  * target-dependent register file definitions, used by regs.[hc]
00400  */
00401 
00402 /* number of integer registers */
00403 #define MD_NUM_IREGS            32
00404 #define MD_NUM_LREGS            1
00405 #define MD_NUM_CTRREGS  1
00406 
00407 /* number of floating point registers */
00408 #define MD_NUM_FREGS            32
00409 
00410 /* number of control registers */
00411 #define MD_NUM_CREGS            3
00412 
00413 /* total number of registers, excluding PC and NPC */
00414 #define MD_TOTAL_REGS                                                   \
00415   (/*int*/32 + /*fp*/32 + /*condition*/1 + /*fpscr*/1 + /*xer*/1 + /*lr*/1+/*ctr*/1)
00416 
00417 /* general purpose (integer) register file entry type */
00418 typedef sword_t md_gpr_t[MD_NUM_IREGS];
00419 
00420 /* floating point register file entry type */
00421 
00422 /*IMP:This structure is different from the PISA/Alpha because PowerPC has 64 bit FP registers*/
00423 
00424 typedef struct {
00425   dfloat_t d[MD_NUM_FREGS];     /* floating point view */
00426 } md_fpr_t;
00427 
00428 /* control register file contents */
00429 typedef struct {
00430 #if 0 // WANT_CHECKPOINT_SUPPORT
00431   BOOST_SERIALIZE {
00432     ar & BOOST_SERIALIZATION_NVP(cr);
00433     ar & BOOST_SERIALIZATION_NVP(xer);
00434     ar & BOOST_SERIALIZATION_NVP(fpscr);
00435   }
00436 #endif
00437   word_t cr, xer;               /* control register and XER register */
00438   word_t fpscr;                 /* floating point status and condition regsiter */
00439 } md_ctrl_t;
00440 
00441 
00442 typedef word_t md_link_t;      /* link regsiter */
00443 typedef word_t md_ctr_t;       /* counter register */
00444 
00445 
00446 /*
00447  * To see the system call conventions on Linux for PPC see
00448  * http://lxr.linux.no/source/include/asm-ppc/unistd.h
00449  *
00450  */
00451 
00452 /* well known registers */
00453 enum md_reg_names {
00454   MD_REG_SP =  1,       /* stack pointer */
00455   MD_REG_FP = 31,       /* frame pointer */
00456   MD_REG_V0 = 3,        /* Return value register */
00457   MD_REG_SC = 0,        /* System call number argument register */
00458   MD_REG_A0 = 3,        /* System call argument registers */
00459   MD_REG_A1 = 4,
00460   MD_REG_A2 = 5, 
00461   MD_REG_A3 = 6 ,
00462   MD_REG_A4 = 7 ,
00463   MD_REG_ERR= 0 ,
00464   MD_REG_ZERO = 0
00465 };
00466 
00467 
00468 /*
00469  * target-dependent instruction format definition
00470  */
00471 /*PowerPc has a 32 bit instruction*/
00472 /* instruction formats */
00473 typedef word_t md_inst_t;
00474 
00475 /* preferred nop instruction definition */
00476 extern md_inst_t MD_NOP_INST;
00477 
00478 
00479 /*
00480  * target-dependent loader module configuration
00481  */
00482 /*For PowerPC other segments starting address is read from the file header by the
00483 loader. So no need to spefcify other segments*/
00484 
00485 /* virtual memory segment limits */
00486 
00487 #define MD_STACK_BASE   0x80000000
00488 
00489 /* maximum size of argc+argv+envp environment */
00490 #define MD_MAX_ENVIRON  131072 /* For PPC :- PAGE_SIZE*MAX_ARG_PAGES . To see this
00491 information, you will have to see the Linux source files as mentioned above*/ 
00492 
00493 
00494 /*
00495  * machine.def specific definitions
00496  */
00497 
00498 /* returns the opcode field value of PowerPC instruction INST */
00499 
00500 /* inst -> enum md_opcode mapping, use this macro to decode insts */
00501 #define MD_TOP_OP(INST)         (((INST) >> 26) & 0x3f)
00502 #define MD_SET_OPCODE(OP, INST)                                        \
00503  {      OP = md_mask2op[((INST>>26)&0x3f)];                            \
00504         while (md_opmask[OP][md_check_mask(INST)])                     \
00505           OP = md_mask2op[((INST) & md_opmask[OP][md_check_mask(INST)])\
00506                          + md_opoffset[OP]];   }
00507 
00508 
00509 /* internal decoder state */
00510 
00511 extern unsigned int md_opoffset[];
00512 extern unsigned int md_opmask[][2];
00513 extern unsigned int md_opshift[];
00514 extern unsigned int md_check_mask(md_inst_t inst);
00515 
00516 
00517 /* global opcode names, these are returned by the decoder (MD_OP_ENUM()) */
00518 
00519 enum md_opcode {
00520   OP_PPC_NA = 0,        /* NA */
00521 #define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3,O3,O4,O5,I4,I5) OP,
00522 #define DEFLINK(OP,MSK,NAME,SHIFT,MASK1,MASK2) OP,
00523 #define CONNECT(OP)
00524 #include "powerpc.def"
00525   OP_MAX        /* number of opcodes + NA */
00526 };
00527 extern enum md_opcode md_mask2op[];
00528 
00529 #undef DEFINST 
00530 
00531 /* largest opcode field value */
00532 #define MD_MAX_MASK             8192
00533 
00534 
00535 
00536 /* inst -> enum md_opcode mapping, use this macro to decode insts */
00537 #define MD_OP_ENUM(MSK)         (md_mask2op[MSK])
00538 extern enum md_opcode md_mask2op[];
00539 
00540 /* enum md_opcode -> description string */
00541 #define MD_OP_NAME(OP)          (md_op2name[OP])
00542 extern const char *md_op2name[];
00543 
00544 /* enum md_opcode -> opcode operand format, used by disassembler */
00545 #define MD_OP_FORMAT(OP)        (md_op2format[OP])
00546 extern const char *md_op2format[];
00547 
00548 /* function unit classes, update md_fu2name if you update this definition */
00549 /* Note: the md_fu_class is now defined in fuClasses.h, not here. */
00550 
00551 /* enum md_opcode -> enum md_fu_class, used by performance simulators */
00552 #define MD_OP_FUCLASS(OP)       (md_op2fu[OP])
00553 extern enum md_fu_class md_op2fu[];
00554 
00555 /* enum md_fu_class -> description string */
00556 #define MD_FU_NAME(FU)          (md_fu2name[FU])
00557 extern const char *md_fu2name[];
00558 
00559 /* instruction flags */
00560 /* Instruction flags are defined in fuClasses.h, not here. */
00561 
00562 /* enum md_opcode -> opcode flags, used by simulators */
00563 #define MD_OP_FLAGS(OP)         (md_op2flags[OP])
00564 extern unsigned int md_op2flags[];
00565 
00566 /* integer register specifiers */
00567 #undef  RS      /* defined in /usr/include/sys/syscall.h on HPUX boxes */
00568 
00569 #define RD              (((CurrentInstruction >> 21) & 0x1f))   /* reg dest */
00570 #define RA              (((CurrentInstruction >> 16) & 0x1f))
00571 #define RB              (((CurrentInstruction >> 11) & 0x1f))
00572 #define RC              (((CurrentInstruction >>  6) & 0x1f))
00573 #define RS              RD
00574 
00575 /* floating point register field synonyms */
00576 #define FS              RS
00577 #define FD              RD
00578 #define FB              RB
00579 #define FA              RA
00580 #define FC              RC
00581 
00582 /*Condition registers fields*/
00583 #define CRBD            RD
00584 #define CRBA            RA
00585 #define CRBB            RB
00586 
00587 #define CRFD            ((inst >> 23) & 0x7)
00588 #define CRFS            ((inst >> 18) & 0x7)
00589 
00590 /* Used in decoding the PowerPC instructions*/
00591 #define MTFSFI_FM       ((inst>>17)&0xff)
00592 #define MTFSFI_IMM      ((inst>>12)&0xf)
00593 #define MB              ( (inst & 0x7C0) >> 6  ) 
00594 #define ME              ( (inst & 0x3E) >> 1 )
00595 #define SPR             ( (inst & 0x001FF800) >> 11 ) 
00596 #define SPRVAL          ( (SPR & 0x1F)+((SPR>>5) & 0x1F) )
00597 #define CRM             ( (inst >> 12) & 0xff ) 
00598 #define TO              RD
00599 #define BO              RD
00600 #define BI              RA
00601 #define BD              ( (inst>>2) & 0x3fff )
00602 #define SH              RB
00603 #define NB              RB
00604 #define LK              (inst & 0x1)
00605 
00606 
00607 #define POSZERODP       0x0000000000000000ll
00608 #define NEGZERODP       0x8000000000000000ll
00609 #define POSINFDP        0x7ff0000000000000ll
00610 #define NEGINFDP        0xfff0000000000000ll
00611 
00612 #define POSZEROSP       0x0000000000000000ll
00613 #define NEGZEROSP       0x8000000000000000ll
00614 #define POSINFSP        0x0ff0000000000000ll
00615 #define NEGINFSP        0x8ff0000000000000ll
00616 
00617 
00618 /* If this bit is set in certain instructions, they are invalid for the
00619 32 bit implementation*/
00620 #define ISSETL          ((inst & 0x00200000)>>21)
00621 
00622 /* returns 16-bit signed immediate field value */
00623 #define IMM             ((int)((/* signed */short)(inst & 0xffff)))
00624 
00625 /* returns 16-bit unsigned immediate field value */
00626 #define UIMM            (inst & 0xffff)
00627 
00628 /* load/store 16-bit signed offset field value, synonym for imm field */
00629 #define OFS             IMM             /* alias to IMM */
00630 
00631 /* Immediate field value for branch instruction*/
00632 #define LI              ((inst & 0x3fffffc))
00633 
00634 #define SEXT24(X)                                                       \
00635   (((X) & 0x800000) ? ((sword_t)(X) | 0xff000000):(sword_t)(X))
00636 
00637 #define SEXT8(X)                                                        \
00638   (((X) & 0x80) ? ((sword_t)(X) | 0xffffff00):(sword_t)(X))
00639 
00640 
00641 #define SEXT16(X)                                                        \
00642   (((X) & 0x8000) ? ((sword_t)(X) | 0xffff0000):(sword_t)(X))
00643 
00644 #define SEXT26(X)                                                        \
00645   (((X) & 0x2000000) ? ((sword_t)(X) | 0xfc000000):(sword_t)(X))
00646 
00647 /*These functions are used to support floating point computations*/
00648 
00649 int isdpNan(qword_t t);
00650 int isdpSNan(qword_t t);
00651 int isdpQNan(qword_t t);
00652 
00653 int isspNan(qword_t t);
00654 int isspSNan(qword_t t);
00655 int isspQNan(qword_t t);
00656 qword_t endian_swap(qword_t value);
00657 dfloat_t convertDWToDouble(qword_t q);
00658 
00659 /* largest signed integer */
00660 #define MAXINT_VAL      0x7fffffff
00661 
00662 /* check for overflow in X+Y, both signed */
00663 #define OVER(X,Y)                                                       \
00664   ((((X) > 0) && ((Y) > 0) && (MAXINT_VAL - (X) < (Y)))                 \
00665    || (((X) < 0) && ((Y) < 0) && (-MAXINT_VAL - (X) > (Y))))
00666 
00667 /* check for underflow in X-Y, both signed */
00668 #define UNDER(X,Y)                                                      \
00669   ((((X) > 0) && ((Y) < 0) && (MAXINT_VAL + (Y) < (X)))                 \
00670    || (((X) < 0) && ((Y) > 0) && (-MAXINT_VAL + (Y) > (X))))
00671 
00672 /*Check for the carry bit */
00673 
00674 int carrygenerated(sword_t a, sword_t b);
00675 
00676 /* default target PC handling */
00677 //#ifndef SET_TPC
00678 //#define SET_TPC(PC)   (void)0
00679 //#endif /* SET_TPC */
00680 
00681 /*
00682  * various other helper macros/functions
00683  */
00684 
00685 /* non-zero if system call is an exit() */
00686 #define SS_SYS_exit                     1
00687 #define MD_EXIT_SYSCALL(REGS)           ((REGS)->regs_R[MD_REG_SC] == SS_SYS_exit)
00688 
00689 /* non-zero if system call is a write to stdout/stderr */
00690 #define SS_SYS_write            4
00691 #define MD_OUTPUT_SYSCALL(REGS)                                         \
00692   ((REGS)->regs_R[MD_REG_SC] == SS_SYS_write                            \
00693        && ((REGS)->regs_R[MD_REG_A0] == /* stdout */1                   \
00694        || (REGS)->regs_R[MD_REG_A0] == /* stderr */2))
00695 
00696 /* returns stream of an output system call, translated to host */
00697 #define MD_STREAM_FILENO(REGS)          ((REGS)->regs_R[MD_REG_A0])
00698 
00699 /* returns non-zero if instruction is a function call */
00700 #define MD_IS_CALL(OP) ((MD_OP_FLAGS(OP) & (F_CTRL|F_CALL)) == (F_CTRL|F_CALL))
00701 
00702 /* returns non-zero if instruction is a function return */
00703 #define MD_IS_RETURN(OP)                (((OP) == BCLR) && ((LK) == 0))
00704 
00705 /* returns non-zero if instruction is an indirect jump */
00706 #define MD_IS_INDIR(OP)                 ( ((OP) == BCCTR) ||((OP) == BCCTRL)|| ((OP) == BCLR) ||((OP) == BCLRL) )
00707 
00708 /* addressing mode probe, enums and strings */
00709 enum md_amode_type {
00710   md_amode_imm,         /* immediate addressing mode */
00711   md_amode_gp,          /* global data access through global pointer */
00712   md_amode_sp,          /* stack access through stack pointer */
00713   md_amode_fp,          /* stack access through frame pointer */
00714   md_amode_disp,        /* (reg + const) addressing */
00715   md_amode_rr,          /* (reg + reg) addressing */
00716   md_amode_NUM
00717 };
00718 extern const char *md_amode_str[md_amode_NUM];
00719 
00720 /* addressing mode pre-probe FSM, must see all instructions */
00721 /*
00722 #define MD_AMODE_PREPROBE(OP, FSM)                                      \
00723   { if ((OP) == LUI) (FSM) = (RT); }
00724 */
00725 
00726 #define MD_AMODE_PREPROBE(OP, FSM) 
00727 #define MD_AMODE_POSTPROBE(FSM) 
00728 
00729 /* compute addressing mode, only for loads/stores */
00730 #define MD_AMODE_PROBE(AM, OP, FSM)                                     \
00731   {                                                                     \
00732     if (MD_OP_FLAGS(OP) & F_DISP)                                       \
00733       {                                                                 \
00734         if ((RA) == MD_REG_SP)                                  \
00735           (AM) = md_amode_sp;                                           \
00736         else                                                            \
00737           (AM) = md_amode_disp;                                         \
00738       }                                                                 \
00739     else if (MD_OP_FLAGS(OP) & F_RR)                                    \
00740       (AM) = md_amode_rr;                                               \
00741     else                                                                \
00742       printf("cannot decode addressing mode");                          \
00743   }
00744 
00745 /*#define MD_AMODE_PROBE(AM, OP, FSM)                                   \
00746   {                                                                     \
00747     if (MD_OP_FLAGS(OP) & F_DISP)                                       \
00748       {                                                                 \
00749         if ((BS) == (FSM))                                              \
00750           (AM) = md_amode_imm;                                          \
00751         else if ((BS) == MD_REG_GP)                                     \
00752           (AM) = md_amode_gp;                                           \
00753         else if ((BS) == MD_REG_SP)                                     \
00754           (AM) = md_amode_sp;                                           \
00755         else if ((BS) == MD_REG_FP)                                     \
00756           (AM) = md_amode_fp;                                           \
00757         else                                                            \
00758           (AM) = md_amode_disp;                                         \
00759       }                                                                 \
00760     else if (MD_OP_FLAGS(OP) & F_RR)                                    \
00761       (AM) = md_amode_rr;                                               \
00762     else                                                                \
00763       printf("cannot decode addressing mode");                          \
00764   }
00765   */
00766 /* addressing mode pre-probe FSM, after all loads and stores */
00767 /*#define MD_AMODE_POSTPROBE(FSM)      { (FSM) = MD_REG_ZERO; }*/
00768 
00769 
00770 /*
00771  * EIO package configuration/macros
00772  */
00773 
00774 /* expected EIO file format */
00775 #define MD_EIO_FILE_FORMAT              EIO_POWERPC_FORMAT
00776 
00777 #define MD_MISC_REGS_TO_EXO(REGS)                                       \
00778   exo_new(ec_list,                                                      \
00779           /*icnt*/exo_new(ec_integer, (exo_integer_t)sim_num_insn),     \
00780           /*PC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_PC),    \
00781           /*NPC*/exo_new(ec_address, (exo_integer_t)(REGS)->regs_NPC),  \
00782           /*CR*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.cr),  \
00783           /*XER*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.xer),\
00784           /*FPSCR*/exo_new(ec_integer, (exo_integer_t)(REGS)->regs_C.fpscr),\
00785           NULL)
00786 
00787 #define MD_IREG_TO_EXO(REGS, IDX)                                       \
00788   exo_new(ec_address, (exo_integer_t)(REGS)->regs_R[IDX])
00789 
00790 /*FixMe : Needs to be fixed for PowerPC since PowerPC has 64 bit FP registers*/
00791 
00792 #define MD_FREG_TO_EXO(REGS, IDX)                                       \
00793   exo_new(ec_address, (exo_integer_t)(REGS)->regs_F.d[IDX])
00794 
00795 
00796 
00797 
00798 #define MD_EXO_TO_MISC_REGS(EXO, ICNT, REGS)                            \
00799   /* check EXO format for errors... */                                  \
00800   if (!exo                                                              \
00801       || exo->ec != ec_list                                             \
00802       || !exo->as_list.head                                             \
00803       || exo->as_list.head->ec != ec_integer                            \
00804       || !exo->as_list.head->next                                       \
00805       || exo->as_list.head->next->ec != ec_address                      \
00806       || !exo->as_list.head->next->next                                 \
00807       || exo->as_list.head->next->next->ec != ec_address                \
00808       || !exo->as_list.head->next->next->next                           \
00809       || exo->as_list.head->next->next->next->ec != ec_integer          \
00810       || !exo->as_list.head->next->next->next->next                     \
00811       || exo->as_list.head->next->next->next->next->ec != ec_integer    \
00812       || !exo->as_list.head->next->next->next->next->next               \
00813       || exo->as_list.head->next->next->next->next->next->ec != ec_integer\
00814       || exo->as_list.head->next->next->next->next->next->next != NULL) \
00815     fatal("could not read EIO misc regs");                              \
00816   (ICNT) = (counter_t)exo->as_list.head->as_integer.val;                \
00817   (REGS)->regs_PC = (md_addr_t)exo->as_list.head->next->as_integer.val; \
00818   (REGS)->regs_NPC =                                                    \
00819     (md_addr_t)exo->as_list.head->next->next->as_integer.val;           \
00820   (REGS)->regs_C.cr =                                                   \
00821     (word_t)exo->as_list.head->next->next->next->as_integer.val;        \
00822   (REGS)->regs_C.xer =                                                  \
00823     (word_t)exo->as_list.head->next->next->next->next->as_integer.val;  \
00824   (REGS)->regs_C.fpscr =                                                        \
00825     (int)exo->as_list.head->next->next->next->next->next->as_integer.val;
00826 
00827 #define MD_EXO_TO_IREG(EXO, REGS, IDX)                                  \
00828   ((REGS)->regs_R[IDX] = (word_t)(EXO)->as_integer.val)
00829 
00830 /*FixMe: The registers in PowerPC are double precision - 64 bit*/
00831 
00832 #define MD_EXO_TO_FREG(EXO, REGS, IDX)                                  \
00833   ((REGS)->regs_F.d[IDX] = (word_t)(EXO)->as_integer.val)
00834 
00835 #define MD_EXO_CMP_IREG(EXO, REGS, IDX)                                 \
00836   ((REGS)->regs_R[IDX] != (sword_t)(EXO)->as_integer.val)
00837 
00838 #define MD_FIRST_IN_REG                 0
00839 #define MD_LAST_IN_REG                  31
00840 
00841 #define MD_FIRST_OUT_REG                0
00842 #define MD_LAST_OUT_REG                 31
00843 
00844 
00845 /*
00846  * configure the EXO package
00847  */
00848 
00849 /* EXO pointer class */
00850 typedef word_t exo_address_t;
00851 
00852 /* EXO integer class, 64-bit encoding */
00853 typedef word_t exo_integer_t;
00854 
00855 /* EXO floating point class, 64-bit encoding */
00856 typedef double exo_float_t;
00857 
00858 
00859 /*
00860  * configure the stats package
00861  */
00862 
00863 /* counter stats */
00864 #ifdef HOST_HAS_QWORD
00865 #define stat_reg_counter                stat_reg_squad
00866 #define sc_counter                      sc_squad
00867 #define for_counter                     for_squad
00868 #else /* !HOST_HAS_QWORD */
00869 #define stat_reg_counter                stat_reg_double
00870 #define sc_counter                      sc_double
00871 #define for_counter                     for_double
00872 #endif /* HOST_HAS_QWORD */
00873 
00874 /* address stats */
00875 #define stat_reg_addr                   stat_reg_uint
00876 
00877 
00878 /*
00879  * configure the DLite! debugger
00880  */
00881 
00882 /* register bank specifier */
00883 enum md_reg_type {
00884         rt_lpr,               /* integer-precison floating point register */
00885         rt_fpr,               /* single-precision floating point register */
00886   rt_gpr,               /* general purpose register */
00887   rt_dpr,               /* double-precision floating pointer register */
00888   rt_link,              /* link register */
00889   rt_cntr,              /* counter register */
00890   rt_ctrl,              /* control register */
00891   rt_PC,                /* program counter */
00892   rt_NPC,               /* next program counter */
00893   rt_NUM
00894 };
00895 
00896 //: register name specifier 
00897 //!IGNORE:
00898 struct md_reg_names_t {
00899   const char *str;                      /* register name */
00900   enum md_reg_type file;        /* register file */
00901   int reg;                      /* register index */
00902 };
00903 
00904 /* symbolic register names, parser is case-insensitive */
00905 extern  md_reg_names_t md_reg_names[];
00906 
00907 /* returns a register name string */
00908 const char *md_reg_name(enum md_reg_type rt, int reg);
00909 
00910 /* default register accessor object */
00911 struct eval_value_t;
00912 struct ppc_regs_t;
00913 const char *                                            /* err str, NULL for no err */
00914 md_reg_obj( ppc_regs_t *regs,                   /* registers to access */
00915            int is_write,                        /* access type */
00916            enum md_reg_type rt,                 /* reg bank to probe */
00917            int reg,                             /* register number */
00918             eval_value_t *val);         /* input, output */
00919 
00920 /* print integer REG(S) to STREAM */
00921 void md_print_ireg(md_gpr_t regs, int reg, FILE *stream);
00922 void md_print_iregs(md_gpr_t regs, FILE *stream);
00923 
00924 /* print floating point REG(S) to STREAM */
00925 void md_print_fpreg(md_fpr_t regs, int reg, FILE *stream);
00926 void md_print_fpregs(md_fpr_t regs, FILE *stream);
00927 
00928 /* print control REG(S) to STREAM */
00929 void md_print_creg(md_ctrl_t regs, int reg, FILE *stream);
00930 void md_print_cregs(md_ctrl_t regs, FILE *stream);
00931 
00932 /* xor checksum registers */
00933 word_t md_xor_regs( ppc_regs_t *regs);
00934 
00935 
00936 /*
00937  * configure sim-outorder specifics
00938  */
00939 
00940 /* primitive operation used to compute addresses within pipeline */
00941 #define MD_AGEN_OP              ADD
00942 
00943 /* NOP operation when injected into the pipeline */
00944 #define MD_NOP_OP       0x18    
00945 
00946 /* non-zero for a valid address, used to determine if speculative accesses
00947    should access the DL1 data cache */
00948 #define MD_VALID_ADDR(ADDR)                                             \
00949   (((ADDR) >= ld_text_base && (ADDR) < (ld_text_base + ld_text_size))   \
00950    || ((ADDR) >= ld_data_base && (ADDR) < ld_stack_base))
00951 
00952 /* this is the address written by the loader for system calls that are imported.
00953 in the 2 word sequence for every sequences, the first word is this value
00954 and the second word is different for each system call. those values
00955 are defined in aixloader.h */
00956 /* in sim-fast we break on a bctr to PPC_SYSCALL_ADDRESS */
00957 #define PPC_SYSCALL_ADDRESS 0x0
00958 
00959 
00960 /*
00961  * configure branch predictors
00962  */
00963 
00964 /* shift used to ignore branch address least significant bits, usually
00965    log2(sizeof(md_inst_t)) */
00966 #define MD_BR_SHIFT             2       /* log2(4) */
00967 
00968 
00969 /*
00970  * target-dependent routines
00971  */
00972 
00973 /* intialize the inst decoder, this function builds the ISA decode tables */
00974 void md_init_decoder(void);
00975 
00976 /* disassemble an inion */
00977 void
00978 md_print_insn(md_inst_t inst,           /* instruction to disassemble */
00979               md_addr_t pc,             /* addr of inst, used for PC-rels */
00980               FILE *stream);            /* output stream */
00981 
00982 /* defines ripped from semantics.c for the instruction implementations copied from there */
00983 
00984 #define CR_LT_BIT ((unsigned int )0x8)
00985 #define CR_GT_BIT ((unsigned int)0x4)
00986 #define CR_EQ_BIT ((unsigned int)0x2)
00987 #define GET_L(_x)       (((_x) >> 21) &  1)
00988 
00989 #define GET_AA(_x)      (((_x) >>  1) &  1)
00990 #define GET_BA(_x)      (((_x) >> 16) & 31)
00991 #define GET_BB(_x)      (((_x) >> 11) & 31)
00992 #define GET_BD(_x)      ((val) ((int16) ((_x) & -4)))
00993 #define GET_BF(_x)      (((_x) >> 23) &  7)
00994 
00995 #define GET_BO(_x)      (((_x) >> 21) & 31)
00996 #define GET_BI(_x)      (((_x) >> 16) & 31)
00997 #define GET_LK(_x)       ((_x)        &  1)
00998 
00999 #define DECREMENTS_CTR(_x) (0 == (GET_BO (_x) & 4))
01000 #define BR_IF_CTR_ZERO(_x) (GET_BO (_x) & 2)
01001 #define CONDITIONAL_BR(_x) (0 == (GET_BO (_x) & 16))
01002 #define BR_IF_TRUE(_x)     (GET_BO (_x) & 8)
01003 
01004 unsigned int sim_mask32(unsigned int start, unsigned int end);
01005 unsigned int sim_rotate_left_32(unsigned int source, unsigned int count);
01006 
01007 /*
01008 unsigned int mask32(unsigned int start, unsigned int end)
01009 {
01010     return(((start > end) ?
01011             ~(((unsigned int)-1 >> start) ^ ((end >= 31) ? 0 : (unsigned int)-1 >> (end + 1)
01012 )):
01013             (((unsigned int)-1 >> start) ^ ((end >= 31) ? 0 : (unsigned int)-1 >> (end+1))))
01014 );
01015 }
01016 
01017 unsigned int rotate_left_32(unsigned int source, unsigned int count)
01018 {
01019     unsigned int value;
01020     
01021     if (count == 0) 
01022         return(source);
01023     
01024     value = source & mask32(0, count-1);
01025     value >>= (32 - count);
01026     value |= (source << count);
01027     
01028     return(value);
01029 }
01030 */
01031 
01032 /* Max buffer sizes when args are passed to system call */
01033 #define PPC_SYSCALL_BUFFER 1024
01034 
01035 void print_bits(void* ptr, int nBytes);
01036 
01037 /* If PowerPC is detected, use assembly in powerpc.def
01038  * otherwise, use softfloat.                        */
01039 //#ifdef __ppc__
01040 //  #define FPU_SOFTFLOAT_MODE 0
01041 //#else
01042 //  #define FPU_SOFTFLOAT_MODE 1
01043 //#endif
01044 
01045 /* _FPSCR_XXXXX
01046  * - specify a hex bitmask for FPSCR bits
01047  */
01048 #define _FPSCR_FX      0x80000000
01049 #define _FPSCR_FEX     0x40000000
01050 #define _FPSCR_VX      0x20000000
01051 #define _FPSCR_OX      0x10000000
01052 #define _FPSCR_UX      0x08000000
01053 #define _FPSCR_ZX      0x04000000
01054 #define _FPSCR_XX      0x02000000
01055 #define _FPSCR_VXSNAN  0x01000000
01056 #define _FPSCR_VXISI   0x00800000
01057 #define _FPSCR_VXIDI   0x00400000
01058 #define _FPSCR_VXZDZ   0x00200000
01059 #define _FPSCR_VXIMZ   0x00100000
01060 #define _FPSCR_VXVC    0x00080000
01061 #define _FPSCR_FR      0x00040000
01062 #define _FPSCR_FI      0x00020000
01063 #define _FPSCR_FPRF    0x0001f000 /* FPRF: complete field mask        */
01064 #define _FPSCR_FPRF_C  0x00010000 /* FPRF bit 15: fp rslt class descptor (C) */
01065 #define _FPSCR_FPRF_16 0x00008000 /* FPRF bit 16: fp < or negative    */
01066 #define _FPSCR_FPRF_17 0x00004000 /* FPRF bit 17: fp > or positive    */
01067 #define _FPSCR_FPRF_18 0x00002000 /* FPRF bit 18: fp equal or zero    */
01068 #define _FPSCR_FPRF_19 0x00001000 /* FPRF bit 19: fp unordered or NaN */
01069 #define _FPSCR_RESRVD  0x00000800
01070 #define _FPSCR_VXSOFT  0x00000400
01071 #define _FPSCR_VXSQRT  0x00000200
01072 #define _FPSCR_VXCVI   0x00000100
01073 #define _FPSCR_VE      0x00000080
01074 #define _FPSCR_OE      0x00000040
01075 #define _FPSCR_UE      0x00000020
01076 #define _FPSCR_ZE      0x00000010
01077 #define _FPSCR_XE      0x00000008
01078 #define _FPSCR_NI      0x00000004
01079 #define _FPSCR_RN      0x00000003 /* MULTI BIT FIELD*/
01080 
01081 
01082 
01083 /* PPCHW_GET_FPSCR_* functions get the values of the 
01084  * various registers in a value storing the FPSCR contents 
01085  * Used for FPU_SOFTFLOAT_MODE */
01086 #define PPCHW_GET_FPSCR_FX(X)      (((X & _FPSCR_FX)     != 0))
01087 #define PPCHW_GET_FPSCR_FEX(X)     (((X & _FPSCR_FEX)    != 0))
01088 #define PPCHW_GET_FPSCR_VX(X)      (((X & _FPSCR_VX)     != 0))
01089 #define PPCHW_GET_FPSCR_OX(X)      (((X & _FPSCR_OX)     != 0))
01090 #define PPCHW_GET_FPSCR_UX(X)      (((X & _FPSCR_UX)     != 0))
01091 #define PPCHW_GET_FPSCR_ZX(X)      (((X & _FPSCR_ZX)     != 0))
01092 #define PPCHW_GET_FPSCR_XX(X)      (((X & _FPSCR_XX)     != 0))
01093 #define PPCHW_GET_FPSCR_VXSNAN(X)  (((X & _FPSCR_VXSNAN) != 0))
01094 #define PPCHW_GET_FPSCR_VXISI(X)   (((X & _FPSCR_VXISI)  != 0))
01095 #define PPCHW_GET_FPSCR_VXIDI(X)   (((X & _FPSCR_VXIDI)  != 0))
01096 #define PPCHW_GET_FPSCR_VXZDZ(X)   (((X & _FPSCR_VXZDZ)  != 0))
01097 #define PPCHW_GET_FPSCR_VXIMZ(X)   (((X & _FPSCR_VXIMZ)  != 0))
01098 #define PPCHW_GET_FPSCR_VXVC(X)    (((X & _FPSCR_VXVC)   != 0))
01099 #define PPCHW_GET_FPSCR_FR(X)      (((X & _FPSCR_FR)     != 0))
01100 #define PPCHW_GET_FPSCR_FI(X)      (((X & _FPSCR_FI)     != 0))
01101 #define PPCHW_GET_FPSCR_FPRF(X)    (((X & (0x1f<<12))>>12))
01102 #define PPCHW_GET_FPSCR_FPCC(X)    (((X & (0x0f<<12))>>12))
01103 #define PPCHW_GET_FPSCR_FPRF_C(X)  (((X & _FPSCR_FPRF_C) != 0))
01104 #define PPCHW_GET_FPSCR_FPRF_16(X) (((X & _FPSCR_FPRF_16)!= 0))
01105 #define PPCHW_GET_FPSCR_FPRF_17(X) (((X & _FPSCR_FPRF_17)!= 0))
01106 #define PPCHW_GET_FPSCR_FPRF_18(X) (((X & _FPSCR_FPRF_18)!= 0))
01107 #define PPCHW_GET_FPSCR_FPRF_19(X) (((X & _FPSCR_FPRF_19)!= 0))
01108 #define PPCHW_GET_FPSCR_RESRVD(X)  (((X & _FPSCR_RESRVD) != 0))
01109 #define PPCHW_GET_FPSCR_VXSOFT(X)  (((X & _FPSCR_VXSOFT) != 0))
01110 #define PPCHW_GET_FPSCR_VXSQRT(X)  (((X & _FPSCR_VXSQRT) != 0))
01111 #define PPCHW_GET_FPSCR_VXCVI(X)   (((X & _FPSCR_VXCVI)  != 0))
01112 #define PPCHW_GET_FPSCR_VE(X)      (((X & _FPSCR_VE)     != 0))
01113 #define PPCHW_GET_FPSCR_OE(X)      (((X & _FPSCR_OE)     != 0))
01114 #define PPCHW_GET_FPSCR_UE(X)      (((X & _FPSCR_UE)     != 0))
01115 #define PPCHW_GET_FPSCR_ZE(X)      (((X & _FPSCR_ZE)     != 0))
01116 #define PPCHW_GET_FPSCR_XE(X)      (((X & _FPSCR_XE)     != 0))
01117 #define PPCHW_GET_FPSCR_NI(X)      (((X & _FPSCR_NI)     != 0))
01118 #define PPCHW_GET_FPSCR_RN(X)      ( (X & _FPSCR_RN) )
01119 
01120 /* PPCHW_SET_FPSCR_* macros allow setting individual bits
01121  * in a word corresponding to the values in the FPSCR 
01122  * used for FPU_SOFTFLOAT_MODE */
01123 #define PPCHW_SET_FPSCR_FX(X)      ((X |= _FPSCR_FX))
01124 #define PPCHW_SET_FPSCR_FEX(X)     ((X |= _FPSCR_FEX))
01125 #define PPCHW_SET_FPSCR_VX(X)      ((X |= _FPSCR_VX))
01126 #define PPCHW_SET_FPSCR_OX(X)      ((X |= _FPSCR_OX))
01127 #define PPCHW_SET_FPSCR_UX(X)      ((X |= _FPSCR_UX))
01128 #define PPCHW_SET_FPSCR_ZX(X)      ((X |= _FPSCR_ZX))
01129 #define PPCHW_SET_FPSCR_XX(X)      ((X |= _FPSCR_XX))
01130 #define PPCHW_SET_FPSCR_VXSNAN(X)  ((X |= _FPSCR_VXSNAN))
01131 #define PPCHW_SET_FPSCR_VXISI(X)   ((X |= _FPSCR_VXISI))
01132 #define PPCHW_SET_FPSCR_VXIDI(X)   ((X |= _FPSCR_VXIDI))
01133 #define PPCHW_SET_FPSCR_VXZDZ(X)   ((X |= _FPSCR_VXZDZ))
01134 #define PPCHW_SET_FPSCR_VXIMZ(X)   ((X |= _FPSCR_VXIMZ))
01135 #define PPCHW_SET_FPSCR_VXVC(X)    ((X |= _FPSCR_VXVC))
01136 #define PPCHW_SET_FPSCR_FR(X)      ((X |= _FPSCR_FR))
01137 #define PPCHW_SET_FPSCR_FI(X)      ((X |= _FPSCR_FI))
01138 #define PPCHW_SET_FPSCR_FPRF(X,V)  ((X |= (V<<12)))     // V <= 16 (0x1f)
01139 #define PPCHW_SET_FPSCR_FPRF_C(X)  ((X |= _FPSCR_FPRF_C))
01140 #define PPCHW_SET_FPSCR_FPRF_16(X) ((X |= _FPSCR_FPRF_16))
01141 #define PPCHW_SET_FPSCR_FPRF_17(X) ((X |= _FPSCR_FPRF_17))
01142 #define PPCHW_SET_FPSCR_FPRF_18(X) ((X |= _FPSCR_FPRF_18))
01143 #define PPCHW_SET_FPSCR_FPRF_19(X) ((X |= _FPSCR_FPRF_19))
01144 #define PPCHW_SET_FPSCR_RESRVD(X)  ((X |= _FPSCR_RESRVD))
01145 #define PPCHW_SET_FPSCR_VXSOFT(X)  ((X |= _FPSCR_VXSOFT))
01146 #define PPCHW_SET_FPSCR_VXSQRT(X)  ((X |= _FPSCR_VXSQRT))
01147 #define PPCHW_SET_FPSCR_VXCVI(X)   ((X |= _FPSCR_VXCVI))
01148 #define PPCHW_SET_FPSCR_VE(X)      ((X |= _FPSCR_VE))
01149 #define PPCHW_SET_FPSCR_OE(X)      ((X |= _FPSCR_OE))
01150 #define PPCHW_SET_FPSCR_UE(X)      ((X |= _FPSCR_UE))
01151 #define PPCHW_SET_FPSCR_ZE(X)      ((X |= _FPSCR_ZE))
01152 #define PPCHW_SET_FPSCR_XE(X)      ((X |= _FPSCR_XE))
01153 #define PPCHW_SET_FPSCR_NI(X)      ((X |= _FPSCR_NI))
01154 #define PPCHW_SET_FPSCR_RN(X,V)    ((X |= V))           // V <= 3 (00,01,10,11)
01155 
01156 #define PPCHW_RESET_FPSCR_FR(X)    (( X &= (~_FPSCR_FR)))
01157 #define PPCHW_RESET_FPSCR_FI(X)    (( X &= (~_FPSCR_FI)))
01158 
01159 
01160 /* wcmclen: following code used in setting FPSCR fields for floating
01161  *          point operations
01162  */
01163 #define FP_ADDOP  1
01164 #define FP_SUBOP  2
01165 #define FP_DIVOP  4
01166 #define FP_MULOP  8
01167 #define FP_SQRTOP 16
01168 #define FP_COMPOP 32
01169 #define FP_ROUNDOP 64
01170 
01171 #define FLAG_DENORM 0x20
01172 #define FLAG_SNAN   0x10
01173 #define FLAG_NAN    0x08
01174 #define FLAG_NEG    0x04
01175 #define FLAG_INF    0x02
01176 #define FLAG_ZERO   0x01
01177 #define TEST_DENORM(X)    (((X & FLAG_DENORM)!=0))
01178 #define TEST_SNAN(X)      (((X & FLAG_SNAN)!=0))
01179 #define TEST_NAN(X)       (((X & FLAG_NAN)!=0))
01180 #define TEST_NEG(X)       (((X & FLAG_NEG)!=0))
01181 #define TEST_INF(X)       (((X & FLAG_INF)!=0))
01182 #define TEST_ZERO(X)      (((X & FLAG_ZERO)!=0))
01183 static inline bool TEST_SNAN_S(const double X) {
01184     unsigned int t;
01185     memcpy(&t, &X, sizeof(unsigned int));
01186     return ((t & (1<<22)) == 0);
01187 }
01188 static inline bool TEST_SNAN_D(const double X) {
01189     unsigned long long t;
01190     memcpy(&t, &X, sizeof(unsigned long long));
01191     return (((t>>51) & 1) == 0);
01192 }
01193 
01194 int FPClassify_D(double value);  // Classify a double precision floating value
01195 int FPClassify_S(float value);   // Classify a single precision floating value
01196 
01197 word_t fpscr_set_D(word_t old_fpscr,     // FPSCR (old)
01198                    int    fp_optype,     // FP_ADDOP, FP_SUBOP, FP_DIVOP, etc.
01199                    double _u,            // result
01200                    double _a,            // operand 1
01201                    double _b,            // operand 2
01202                    int sf_EFlags,        // softfloat_exception_flags
01203                    int sf_RFlags);       // softfloat_rounding_flags
01204 
01205 word_t fpscr_set_S(word_t old_fpscr,
01206                    int fp_optype,
01207                    float _u,
01208                    float _a,
01209                    float _b,
01210                    int sf_EFlags,
01211                    int sf_RFlags);
01212 
01213 void print_fpscr_bits(word_t _fpscr);
01214 
01215 
01216 #endif /* POWERPC_H */
01217 /* EOF */

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