Home | History | Annotate | Line # | Download | only in d10v
      1  1.1  christos #ifndef D10V_SIM_H
      2  1.1  christos #define D10V_SIM_H
      3  1.1  christos 
      4  1.1  christos #include <stdio.h>
      5  1.1  christos #include <ctype.h>
      6  1.1  christos #include <limits.h>
      7  1.1  christos #include "ansidecl.h"
      8  1.1  christos #include "sim/callback.h"
      9  1.1  christos #include "opcode/d10v.h"
     10  1.1  christos #include "bfd.h"
     11  1.1  christos 
     12  1.1  christos #define DEBUG_TRACE		0x00000001
     13  1.1  christos #define DEBUG_VALUES		0x00000002
     14  1.1  christos #define DEBUG_LINE_NUMBER	0x00000004
     15  1.1  christos #define DEBUG_MEMSIZE		0x00000008
     16  1.1  christos #define DEBUG_INSTRUCTION	0x00000010
     17  1.1  christos #define DEBUG_TRAP		0x00000020
     18  1.1  christos #define DEBUG_MEMORY		0x00000040
     19  1.1  christos 
     20  1.1  christos #ifndef	DEBUG
     21  1.1  christos #define	DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER)
     22  1.1  christos #endif
     23  1.1  christos 
     24  1.1  christos extern int d10v_debug;
     25  1.1  christos 
     26  1.1  christos #include "sim/sim.h"
     27  1.1  christos #include "sim-config.h"
     28  1.1  christos #include "sim-types.h"
     29  1.1  christos 
     30  1.1  christos /* FIXME: D10V defines */
     31  1.1  christos typedef uint16_t reg_t;
     32  1.1  christos 
     33  1.1  christos struct simops
     34  1.1  christos {
     35  1.1  christos   long opcode;
     36  1.1  christos   int  is_long;
     37  1.1  christos   long mask;
     38  1.1  christos   int format;
     39  1.1  christos   int cycles;
     40  1.1  christos   int unit;
     41  1.1  christos   int exec_type;
     42  1.1  christos   void (*func)(SIM_DESC, SIM_CPU *);
     43  1.1  christos   int numops;
     44  1.1  christos   int operands[9];
     45  1.1  christos };
     46  1.1  christos 
     47  1.1  christos enum _ins_type
     48  1.1  christos {
     49  1.1  christos   INS_UNKNOWN,			/* unknown instruction */
     50  1.1  christos   INS_COND_TRUE,		/* # times EXExxx executed other instruction */
     51  1.1  christos   INS_COND_FALSE,		/* # times EXExxx did not execute other instruction */
     52  1.1  christos   INS_COND_JUMP,		/* # times JUMP skipped other instruction */
     53  1.1  christos   INS_CYCLES,			/* # cycles */
     54  1.1  christos   INS_LONG,			/* long instruction (both containers, ie FM == 11) */
     55  1.1  christos   INS_LEFTRIGHT,		/* # times instruction encoded as L -> R (ie, FM == 01) */
     56  1.1  christos   INS_RIGHTLEFT,		/* # times instruction encoded as L <- R (ie, FM == 10) */
     57  1.1  christos   INS_PARALLEL,			/* # times instruction encoded as L || R (ie, RM == 00) */
     58  1.1  christos 
     59  1.1  christos   INS_LEFT,			/* normal left instructions */
     60  1.1  christos   INS_LEFT_PARALLEL,		/* left side of || */
     61  1.1  christos   INS_LEFT_COND_TEST,		/* EXExx test on left side */
     62  1.1  christos   INS_LEFT_COND_EXE,		/* execution after EXExxx test on right side succeeded */
     63  1.1  christos   INS_LEFT_NOPS,		/* NOP on left side */
     64  1.1  christos 
     65  1.1  christos   INS_RIGHT,			/* normal right instructions */
     66  1.1  christos   INS_RIGHT_PARALLEL,		/* right side of || */
     67  1.1  christos   INS_RIGHT_COND_TEST,		/* EXExx test on right side */
     68  1.1  christos   INS_RIGHT_COND_EXE,		/* execution after EXExxx test on left side succeeded */
     69  1.1  christos   INS_RIGHT_NOPS,		/* NOP on right side */
     70  1.1  christos 
     71  1.1  christos   INS_MAX
     72  1.1  christos };
     73  1.1  christos 
     74  1.1  christos extern unsigned long ins_type_counters[ (int)INS_MAX ];
     75  1.1  christos 
     76  1.1  christos enum {
     77  1.1  christos   SP_IDX = 15,
     78  1.1  christos };
     79  1.1  christos 
     80  1.1  christos /* Write-back slots */
     81  1.1  christos union slot_data {
     82  1.1  christos   unsigned_1 _1;
     83  1.1  christos   unsigned_2 _2;
     84  1.1  christos   unsigned_4 _4;
     85  1.1  christos   unsigned_8 _8;
     86  1.1  christos };
     87  1.1  christos struct slot {
     88  1.1  christos   void *dest;
     89  1.1  christos   int size;
     90  1.1  christos   union slot_data data;
     91  1.1  christos   union slot_data mask;
     92  1.1  christos };
     93  1.1  christos enum {
     94  1.1  christos  NR_SLOTS = 16,
     95  1.1  christos };
     96  1.1  christos #define SLOT (State.slot)
     97  1.1  christos #define SLOT_NR (State.slot_nr)
     98  1.1  christos #define SLOT_PEND_MASK(DEST, MSK, VAL) \
     99  1.1  christos   do \
    100  1.1  christos     { \
    101  1.1  christos       SLOT[SLOT_NR].dest = &(DEST); \
    102  1.1  christos       SLOT[SLOT_NR].size = sizeof (DEST); \
    103  1.1  christos       switch (sizeof (DEST)) \
    104  1.1  christos         { \
    105  1.1  christos         case 1: \
    106  1.1  christos           SLOT[SLOT_NR].data._1 = (unsigned_1) (VAL); \
    107  1.1  christos           SLOT[SLOT_NR].mask._1 = (unsigned_1) (MSK); \
    108  1.1  christos           break; \
    109  1.1  christos         case 2: \
    110  1.1  christos           SLOT[SLOT_NR].data._2 = (unsigned_2) (VAL); \
    111  1.1  christos           SLOT[SLOT_NR].mask._2 = (unsigned_2) (MSK); \
    112  1.1  christos           break; \
    113  1.1  christos         case 4: \
    114  1.1  christos           SLOT[SLOT_NR].data._4 = (unsigned_4) (VAL); \
    115  1.1  christos           SLOT[SLOT_NR].mask._4 = (unsigned_4) (MSK); \
    116  1.1  christos           break; \
    117  1.1  christos         case 8: \
    118  1.1  christos           SLOT[SLOT_NR].data._8 = (unsigned_8) (VAL); \
    119  1.1  christos           SLOT[SLOT_NR].mask._8 = (unsigned_8) (MSK); \
    120  1.1  christos           break; \
    121  1.1  christos         } \
    122  1.1  christos       SLOT_NR = (SLOT_NR + 1); \
    123  1.1  christos     } \
    124  1.1  christos   while (0)
    125  1.1  christos #define SLOT_PEND(DEST, VAL) SLOT_PEND_MASK(DEST, 0, VAL)
    126  1.1  christos #define SLOT_DISCARD() (SLOT_NR = 0)
    127  1.1  christos #define SLOT_FLUSH() \
    128  1.1  christos   do \
    129  1.1  christos     { \
    130  1.1  christos       int i; \
    131  1.1  christos       for (i = 0; i < SLOT_NR; i++) \
    132  1.1  christos 	{ \
    133  1.1  christos 	  switch (SLOT[i].size) \
    134  1.1  christos 	    { \
    135  1.1  christos 	    case 1: \
    136  1.1  christos 	      *(unsigned_1*) SLOT[i].dest &= SLOT[i].mask._1; \
    137  1.1  christos 	      *(unsigned_1*) SLOT[i].dest |= SLOT[i].data._1; \
    138  1.1  christos 	      break; \
    139  1.1  christos 	    case 2: \
    140  1.1  christos 	      *(unsigned_2*) SLOT[i].dest &= SLOT[i].mask._2; \
    141  1.1  christos 	      *(unsigned_2*) SLOT[i].dest |= SLOT[i].data._2; \
    142  1.1  christos 	      break; \
    143  1.1  christos 	    case 4: \
    144  1.1  christos 	      *(unsigned_4*) SLOT[i].dest &= SLOT[i].mask._4; \
    145  1.1  christos 	      *(unsigned_4*) SLOT[i].dest |= SLOT[i].data._4; \
    146  1.1  christos 	      break; \
    147  1.1  christos 	    case 8: \
    148  1.1  christos 	      *(unsigned_8*) SLOT[i].dest &= SLOT[i].mask._8; \
    149  1.1  christos 	      *(unsigned_8*) SLOT[i].dest |= SLOT[i].data._8; \
    150  1.1  christos 	      break; \
    151  1.1  christos 	    } \
    152  1.1  christos         } \
    153  1.1  christos       SLOT_NR = 0; \
    154  1.1  christos     } \
    155  1.1  christos   while (0)
    156  1.1  christos #define SLOT_DUMP() \
    157  1.1  christos   do \
    158  1.1  christos     { \
    159  1.1  christos       int i; \
    160  1.1  christos       for (i = 0; i < SLOT_NR; i++) \
    161  1.1  christos 	{ \
    162  1.1  christos 	  switch (SLOT[i].size) \
    163  1.1  christos 	    { \
    164  1.1  christos 	    case 1: \
    165  1.1  christos               printf ("SLOT %d *0x%08lx & 0x%02x | 0x%02x\n", i, \
    166  1.1  christos 		      (long) SLOT[i].dest, \
    167  1.1  christos                       (unsigned) SLOT[i].mask._1, \
    168  1.1  christos                       (unsigned) SLOT[i].data._1); \
    169  1.1  christos 	      break; \
    170  1.1  christos 	    case 2: \
    171  1.1  christos               printf ("SLOT %d *0x%08lx & 0x%04x | 0x%04x\n", i, \
    172  1.1  christos 		      (long) SLOT[i].dest, \
    173  1.1  christos                       (unsigned) SLOT[i].mask._2, \
    174  1.1  christos                       (unsigned) SLOT[i].data._2); \
    175  1.1  christos 	      break; \
    176  1.1  christos 	    case 4: \
    177  1.1  christos               printf ("SLOT %d *0x%08lx & 0x%08x | 0x%08x\n", i, \
    178  1.1  christos 		      (long) SLOT[i].dest, \
    179  1.1  christos                       (unsigned) SLOT[i].mask._4, \
    180  1.1  christos                       (unsigned) SLOT[i].data._4); \
    181  1.1  christos 	      break; \
    182  1.1  christos 	    case 8: \
    183  1.1  christos               printf ("SLOT %d *0x%08lx & 0x%08x%08x | 0x%08x%08x\n", i, \
    184  1.1  christos 		      (long) SLOT[i].dest, \
    185  1.1  christos                       (unsigned) (SLOT[i].mask._8 >> 32),  \
    186  1.1  christos                       (unsigned) SLOT[i].mask._8, \
    187  1.1  christos                       (unsigned) (SLOT[i].data._8 >> 32),  \
    188  1.1  christos                       (unsigned) SLOT[i].data._8); \
    189  1.1  christos 	      break; \
    190  1.1  christos 	    } \
    191  1.1  christos         } \
    192  1.1  christos     } \
    193  1.1  christos   while (0)
    194  1.1  christos 
    195  1.1  christos /* d10v memory: There are three separate d10v memory regions IMEM,
    196  1.1  christos    UMEM and DMEM.  The IMEM and DMEM are further broken down into
    197  1.1  christos    blocks (very like VM pages). */
    198  1.1  christos 
    199  1.1  christos enum
    200  1.1  christos {
    201  1.1  christos   IMAP_BLOCK_SIZE = 0x20000,
    202  1.1  christos   DMAP_BLOCK_SIZE = 0x4000,
    203  1.1  christos };
    204  1.1  christos 
    205  1.1  christos /* Implement the three memory regions using sparse arrays.  Allocate
    206  1.1  christos    memory using ``segments''.  A segment must be at least as large as
    207  1.1  christos    a BLOCK - ensures that an access that doesn't cross a block
    208  1.1  christos    boundary can't cross a segment boundary */
    209  1.1  christos 
    210  1.1  christos enum
    211  1.1  christos {
    212  1.1  christos   SEGMENT_SIZE = 0x20000, /* 128KB - MAX(IMAP_BLOCK_SIZE,DMAP_BLOCK_SIZE) */
    213  1.1  christos   IMEM_SEGMENTS = 8, /* 1MB */
    214  1.1  christos   DMEM_SEGMENTS = 8, /* 1MB */
    215  1.1  christos   UMEM_SEGMENTS = 128 /* 16MB */
    216  1.1  christos };
    217  1.1  christos 
    218  1.1  christos struct d10v_memory
    219  1.1  christos {
    220  1.1  christos   uint8_t *insn[IMEM_SEGMENTS];
    221  1.1  christos   uint8_t *data[DMEM_SEGMENTS];
    222  1.1  christos   uint8_t *unif[UMEM_SEGMENTS];
    223  1.1  christos };
    224  1.1  christos 
    225  1.1  christos struct _state
    226  1.1  christos {
    227  1.1  christos   reg_t regs[16];		/* general-purpose registers */
    228  1.1  christos #define GPR(N) (State.regs[(N)] + 0)
    229  1.1  christos #define SET_GPR(N,VAL) SLOT_PEND (State.regs[(N)], (VAL))
    230  1.1  christos 
    231  1.1  christos #define GPR32(N) ((((uint32_t) State.regs[(N) + 0]) << 16) \
    232  1.1  christos 		  | (uint16_t) State.regs[(N) + 1])
    233  1.1  christos #define SET_GPR32(N,VAL) do { SET_GPR (OP[0] + 0, (VAL) >> 16); SET_GPR (OP[0] + 1, (VAL)); } while (0)
    234  1.1  christos 
    235  1.1  christos   reg_t cregs[16];		/* control registers */
    236  1.1  christos #define CREG(N) (State.cregs[(N)] + 0)
    237  1.1  christos #define SET_CREG(N,VAL) move_to_cr (sd, cpu, (N), 0, (VAL), 0)
    238  1.1  christos #define SET_HW_CREG(N,VAL) move_to_cr (sd, cpu, (N), 0, (VAL), 1)
    239  1.1  christos 
    240  1.1  christos   reg_t sp[2];                  /* holding area for SPI(0)/SPU(1) */
    241  1.1  christos #define HELD_SP(N) (State.sp[(N)] + 0)
    242  1.1  christos #define SET_HELD_SP(N,VAL) SLOT_PEND (State.sp[(N)], (VAL))
    243  1.1  christos 
    244  1.1  christos   int64_t a[2];			/* accumulators */
    245  1.1  christos #define ACC(N) (State.a[(N)] + 0)
    246  1.1  christos #define SET_ACC(N,VAL) SLOT_PEND (State.a[(N)], (VAL) & MASK40)
    247  1.1  christos 
    248  1.1  christos   /* writeback info */
    249  1.1  christos   struct slot slot[NR_SLOTS];
    250  1.1  christos   int slot_nr;
    251  1.1  christos 
    252  1.1  christos   /* trace data */
    253  1.1  christos   struct {
    254  1.1  christos     uint16_t psw;
    255  1.1  christos   } trace;
    256  1.1  christos 
    257  1.1  christos   uint8_t exe;
    258  1.1  christos   int	pc_changed;
    259  1.1  christos 
    260  1.1  christos   /* NOTE: everything below this line is not reset by
    261  1.1  christos      sim_create_inferior() */
    262  1.1  christos 
    263  1.1  christos   struct d10v_memory mem;
    264  1.1  christos 
    265  1.1  christos   enum _ins_type ins_type;
    266  1.1  christos 
    267  1.1  christos };
    268  1.1  christos 
    269  1.1  christos extern struct _state State;
    270  1.1  christos 
    271  1.1  christos 
    272  1.1  christos extern uint16_t OP[4];
    273  1.1  christos extern struct simops Simops[];
    274  1.1  christos 
    275  1.1  christos enum
    276  1.1  christos {
    277  1.1  christos   PSW_CR = 0,
    278  1.1  christos   BPSW_CR = 1,
    279  1.1  christos   PC_CR = 2,
    280  1.1  christos   BPC_CR = 3,
    281  1.1  christos   DPSW_CR = 4,
    282  1.1  christos   DPC_CR = 5,
    283  1.1  christos   RPT_C_CR = 7,
    284  1.1  christos   RPT_S_CR = 8,
    285  1.1  christos   RPT_E_CR = 9,
    286  1.1  christos   MOD_S_CR = 10,
    287  1.1  christos   MOD_E_CR = 11,
    288  1.1  christos   IBA_CR = 14,
    289  1.1  christos };
    290  1.1  christos 
    291  1.1  christos enum
    292  1.1  christos {
    293  1.1  christos   PSW_SM_BIT = 0x8000,
    294  1.1  christos   PSW_EA_BIT = 0x2000,
    295  1.1  christos   PSW_DB_BIT = 0x1000,
    296  1.1  christos   PSW_DM_BIT = 0x0800,
    297  1.1  christos   PSW_IE_BIT = 0x0400,
    298  1.1  christos   PSW_RP_BIT = 0x0200,
    299  1.1  christos   PSW_MD_BIT = 0x0100,
    300  1.1  christos   PSW_FX_BIT = 0x0080,
    301  1.1  christos   PSW_ST_BIT = 0x0040,
    302  1.1  christos   PSW_F0_BIT = 0x0008,
    303  1.1  christos   PSW_F1_BIT = 0x0004,
    304  1.1  christos   PSW_C_BIT =  0x0001,
    305  1.1  christos };
    306  1.1  christos 
    307  1.1  christos #define PSW CREG (PSW_CR)
    308  1.1  christos #define SET_PSW(VAL) SET_CREG (PSW_CR, (VAL))
    309  1.1  christos #define SET_HW_PSW(VAL) SET_HW_CREG (PSW_CR, (VAL))
    310  1.1  christos #define SET_PSW_BIT(MASK,VAL) move_to_cr (sd, cpu, PSW_CR, ~((reg_t) MASK), (VAL) ? (MASK) : 0, 1)
    311  1.1  christos 
    312  1.1  christos #define PSW_SM ((PSW & PSW_SM_BIT) != 0)
    313  1.1  christos #define SET_PSW_SM(VAL) SET_PSW_BIT (PSW_SM_BIT, (VAL))
    314  1.1  christos 
    315  1.1  christos #define PSW_EA ((PSW & PSW_EA_BIT) != 0)
    316  1.1  christos #define SET_PSW_EA(VAL) SET_PSW_BIT (PSW_EA_BIT, (VAL))
    317  1.1  christos 
    318  1.1  christos #define PSW_DB ((PSW & PSW_DB_BIT) != 0)
    319  1.1  christos #define SET_PSW_DB(VAL) SET_PSW_BIT (PSW_DB_BIT, (VAL))
    320  1.1  christos 
    321  1.1  christos #define PSW_DM ((PSW & PSW_DM_BIT) != 0)
    322  1.1  christos #define SET_PSW_DM(VAL) SET_PSW_BIT (PSW_DM_BIT, (VAL))
    323  1.1  christos 
    324  1.1  christos #define PSW_IE ((PSW & PSW_IE_BIT) != 0)
    325  1.1  christos #define SET_PSW_IE(VAL) SET_PSW_BIT (PSW_IE_BIT, (VAL))
    326  1.1  christos 
    327  1.1  christos #define PSW_RP ((PSW & PSW_RP_BIT) != 0)
    328  1.1  christos #define SET_PSW_RP(VAL) SET_PSW_BIT (PSW_RP_BIT, (VAL))
    329  1.1  christos 
    330  1.1  christos #define PSW_MD ((PSW & PSW_MD_BIT) != 0)
    331  1.1  christos #define SET_PSW_MD(VAL) SET_PSW_BIT (PSW_MD_BIT, (VAL))
    332  1.1  christos 
    333  1.1  christos #define PSW_FX ((PSW & PSW_FX_BIT) != 0)
    334  1.1  christos #define SET_PSW_FX(VAL) SET_PSW_BIT (PSW_FX_BIT, (VAL))
    335  1.1  christos 
    336  1.1  christos #define PSW_ST ((PSW & PSW_ST_BIT) != 0)
    337  1.1  christos #define SET_PSW_ST(VAL) SET_PSW_BIT (PSW_ST_BIT, (VAL))
    338  1.1  christos 
    339  1.1  christos #define PSW_F0 ((PSW & PSW_F0_BIT) != 0)
    340  1.1  christos #define SET_PSW_F0(VAL) SET_PSW_BIT (PSW_F0_BIT, (VAL))
    341  1.1  christos 
    342  1.1  christos #define PSW_F1 ((PSW & PSW_F1_BIT) != 0)
    343  1.1  christos #define SET_PSW_F1(VAL) SET_PSW_BIT (PSW_F1_BIT, (VAL))
    344  1.1  christos 
    345  1.1  christos #define PSW_C ((PSW & PSW_C_BIT) != 0)
    346  1.1  christos #define SET_PSW_C(VAL) SET_PSW_BIT (PSW_C_BIT, (VAL))
    347  1.1  christos 
    348  1.1  christos /* See simopsc.:move_to_cr() for registers that can not be read-from
    349  1.1  christos    or assigned-to directly */
    350  1.1  christos 
    351  1.1  christos #define PC	CREG (PC_CR)
    352  1.1  christos #define SET_PC(VAL) SET_CREG (PC_CR, (VAL))
    353  1.1  christos 
    354  1.1  christos #define BPSW	CREG (BPSW_CR)
    355  1.1  christos #define SET_BPSW(VAL) SET_CREG (BPSW_CR, (VAL))
    356  1.1  christos 
    357  1.1  christos #define BPC	CREG (BPC_CR)
    358  1.1  christos #define SET_BPC(VAL) SET_CREG (BPC_CR, (VAL))
    359  1.1  christos 
    360  1.1  christos #define DPSW	CREG (DPSW_CR)
    361  1.1  christos #define SET_DPSW(VAL) SET_CREG (DPSW_CR, (VAL))
    362  1.1  christos 
    363  1.1  christos #define DPC	CREG (DPC_CR)
    364  1.1  christos #define SET_DPC(VAL) SET_CREG (DPC_CR, (VAL))
    365  1.1  christos 
    366  1.1  christos #define RPT_C	CREG (RPT_C_CR)
    367  1.1  christos #define SET_RPT_C(VAL) SET_CREG (RPT_C_CR, (VAL))
    368  1.1  christos 
    369  1.1  christos #define RPT_S	CREG (RPT_S_CR)
    370  1.1  christos #define SET_RPT_S(VAL) SET_CREG (RPT_S_CR, (VAL))
    371  1.1  christos 
    372  1.1  christos #define RPT_E	CREG (RPT_E_CR)
    373  1.1  christos #define SET_RPT_E(VAL) SET_CREG (RPT_E_CR, (VAL))
    374  1.1  christos 
    375  1.1  christos #define MOD_S	CREG (MOD_S_CR)
    376  1.1  christos #define SET_MOD_S(VAL) SET_CREG (MOD_S_CR, (VAL))
    377  1.1  christos 
    378  1.1  christos #define MOD_E	CREG (MOD_E_CR)
    379  1.1  christos #define SET_MOD_E(VAL) SET_CREG (MOD_E_CR, (VAL))
    380  1.1  christos 
    381  1.1  christos #define IBA	CREG (IBA_CR)
    382  1.1  christos #define SET_IBA(VAL) SET_CREG (IBA_CR, (VAL))
    383  1.1  christos 
    384  1.1  christos 
    385  1.1  christos #define SIG_D10V_STOP	-1
    386  1.1  christos #define SIG_D10V_EXIT	-2
    387  1.1  christos #define SIG_D10V_BUS    -3
    388  1.1  christos 
    389  1.1  christos /* TODO: Resolve conflicts with common headers.  */
    390  1.1  christos #undef SEXT8
    391  1.1  christos #undef SEXT16
    392  1.1  christos #undef SEXT32
    393  1.1  christos #undef MASK32
    394  1.1  christos 
    395  1.1  christos #define SEXT3(x)	((((x)&0x7)^(~3))+4)
    396  1.1  christos 
    397  1.1  christos /* sign-extend a 4-bit number */
    398  1.1  christos #define SEXT4(x)	((((x)&0xf)^(~7))+8)
    399  1.1  christos 
    400  1.1  christos /* sign-extend an 8-bit number */
    401  1.1  christos #define SEXT8(x)	((((x)&0xff)^(~0x7f))+0x80)
    402  1.1  christos 
    403  1.1  christos /* sign-extend a 16-bit number */
    404  1.1  christos #define SEXT16(x)	((((x)&0xffff)^(~0x7fff))+0x8000)
    405  1.1  christos 
    406  1.1  christos /* sign-extend a 32-bit number */
    407  1.1  christos #define SEXT32(x)	((((x)&SIGNED64(0xffffffff))^(~SIGNED64(0x7fffffff)))+SIGNED64(0x80000000))
    408  1.1  christos 
    409  1.1  christos /* sign extend a 40 bit number */
    410  1.1  christos #define SEXT40(x)	((((x)&SIGNED64(0xffffffffff))^(~SIGNED64(0x7fffffffff)))+SIGNED64(0x8000000000))
    411  1.1  christos 
    412  1.1  christos /* sign extend a 44 bit number */
    413  1.1  christos #define SEXT44(x)	((((x)&SIGNED64(0xfffffffffff))^(~SIGNED64(0x7ffffffffff)))+SIGNED64(0x80000000000))
    414  1.1  christos 
    415  1.1  christos /* sign extend a 56 bit number */
    416  1.1  christos #define SEXT56(x)	((((x)&SIGNED64(0xffffffffffffff))^(~SIGNED64(0x7fffffffffffff)))+SIGNED64(0x80000000000000))
    417  1.1  christos 
    418  1.1  christos /* sign extend a 60 bit number */
    419  1.1  christos #define SEXT60(x)	((((x)&SIGNED64(0xfffffffffffffff))^(~SIGNED64(0x7ffffffffffffff)))+SIGNED64(0x800000000000000))
    420  1.1  christos 
    421  1.1  christos #define MAX32	SIGNED64(0x7fffffff)
    422  1.1  christos #define MIN32	SIGNED64(0xff80000000)
    423  1.1  christos #define MASK32	SIGNED64(0xffffffff)
    424  1.1  christos #define MASK40	SIGNED64(0xffffffffff)
    425  1.1  christos 
    426  1.1  christos /* The alignment of MOD_E in the following macro depends upon "i"
    427  1.1  christos    always being a power of 2. */
    428  1.1  christos #define INC_ADDR(x,i) \
    429  1.1  christos do \
    430  1.1  christos   { \
    431  1.1  christos     int test_i = i < 0 ? i : ~((i) - 1); \
    432  1.1  christos     if (PSW_MD && GPR (x) == (MOD_E & test_i)) \
    433  1.1  christos       SET_GPR (x, MOD_S & test_i); \
    434  1.1  christos     else \
    435  1.1  christos       SET_GPR (x, GPR (x) + (i)); \
    436  1.1  christos   } \
    437  1.1  christos while (0)
    438  1.1  christos 
    439  1.1  christos extern uint8_t *dmem_addr (SIM_DESC, SIM_CPU *, uint16_t offset);
    440  1.1  christos extern uint8_t *imem_addr (SIM_DESC, SIM_CPU *, uint32_t);
    441  1.1  christos 
    442  1.1  christos #define	RB(x)	(*(dmem_addr (sd, cpu, x)))
    443  1.1  christos #define SB(addr,data)	( RB(addr) = (data & 0xff))
    444  1.1  christos 
    445  1.1  christos #if defined(__GNUC__) && defined(__OPTIMIZE__) && !defined(NO_ENDIAN_INLINE)
    446  1.1  christos #define ENDIAN_INLINE static __inline__
    447  1.1  christos #include "endian.c"
    448  1.1  christos #undef ENDIAN_INLINE
    449  1.1  christos 
    450  1.1  christos #else
    451  1.1  christos extern uint32_t get_longword (const uint8_t *);
    452  1.1  christos extern uint16_t get_word (const uint8_t *);
    453  1.1  christos extern int64_t get_longlong (const uint8_t *);
    454  1.1  christos extern void write_word (uint8_t *addr, uint16_t data);
    455  1.1  christos extern void write_longword (uint8_t *addr, uint32_t data);
    456  1.1  christos extern void write_longlong (uint8_t *addr, int64_t data);
    457  1.1  christos #endif
    458  1.1  christos 
    459  1.1  christos #define SW(addr,data)		write_word (dmem_addr (sd, cpu, addr), data)
    460  1.1  christos #define RW(x)			get_word (dmem_addr (sd, cpu, x))
    461  1.1  christos #define SLW(addr,data)  	write_longword (dmem_addr (sd, cpu, addr), data)
    462  1.1  christos #define RLW(x)			get_longword (dmem_addr (sd, cpu, x))
    463  1.1  christos #define READ_16(x)		get_word(x)
    464  1.1  christos #define WRITE_16(addr,data)	write_word(addr,data)
    465  1.1  christos #define READ_64(x)		get_longlong(x)
    466  1.1  christos #define WRITE_64(addr,data)	write_longlong(addr,data)
    467  1.1  christos 
    468  1.1  christos #define JMP(x)			do { SET_PC (x); State.pc_changed = 1; } while (0)
    469  1.1  christos 
    470  1.1  christos #define RIE_VECTOR_START 0xffc2
    471  1.1  christos #define AE_VECTOR_START 0xffc3
    472  1.1  christos #define TRAP_VECTOR_START 0xffc4	/* vector for trap 0 */
    473  1.1  christos #define DBT_VECTOR_START 0xffd4
    474  1.1  christos #define SDBT_VECTOR_START 0xffd5
    475  1.1  christos 
    476  1.1  christos /* Scedule a store of VAL into cr[CR].  MASK indicates the bits in
    477  1.1  christos    cr[CR] that should not be modified (i.e. cr[CR] = (cr[CR] & MASK) |
    478  1.1  christos    (VAL & ~MASK)).  In addition, unless PSW_HW_P, a VAL intended for
    479  1.1  christos    PSW is masked for zero bits. */
    480  1.1  christos 
    481  1.1  christos extern reg_t move_to_cr (SIM_DESC, SIM_CPU *, int cr, reg_t mask, reg_t val, int psw_hw_p);
    482  1.1  christos 
    483  1.1  christos #endif
    484