home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / GDB / GDB-4.13 / GDB-4 / gdb-4.13 / sim / z8k / inlines.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-02  |  11.5 KB  |  617 lines

  1. /* inline functions for Z8KSIM
  2.    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of Z8KSIM
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #ifndef INLINE
  21. #define INLINE
  22. #endif
  23. #define UGT 0x0b
  24. #define ULE 0x03
  25. #define ULT 0x07
  26. #define UGE 0x0f
  27. #define SLOW 0
  28. #define T 0x8
  29. #define F 0x0
  30. #define LT 0x1
  31. #define GT 0xa
  32. #define LE 0x2
  33. #define EQ 0x6
  34. #define NE 0xe
  35. #define GE 0x9
  36.  
  37.  static int is_cond_true PARAMS((sim_state_type *context, int c)); 
  38.  static void makeflags PARAMS((sim_state_type *context, int mask)); 
  39.  
  40. INLINE
  41. long
  42. sitoptr (si)
  43. long si;
  44. {
  45.   return ((si & 0xff000000) >> 8) | (si & 0xffff);
  46. }
  47. INLINE long
  48. ptrtosi (ptr)
  49. long ptr;
  50. {
  51.   return ((ptr & 0xff0000) << 8) | (ptr & 0xffff);
  52. }
  53.  
  54. INLINE
  55. void 
  56. put_long_reg (context, reg, val)
  57.      sim_state_type *context;
  58.      int reg;
  59.      int val;
  60. {
  61.   context->regs[reg].word = val >> 16;
  62.   context->regs[reg + 1].word = val;
  63. }
  64.  
  65. INLINE
  66. void 
  67. put_quad_reg (context, reg, val1, val2)
  68.      sim_state_type *context;
  69.      int reg;
  70.      int val1;
  71.      int val2;
  72. {
  73.   context->regs[reg].word = val2 >> 16;
  74.   context->regs[reg + 1].word = val2;
  75.   context->regs[reg + 2].word = val1 >> 16;
  76.   context->regs[reg + 3].word = val1;
  77. }
  78.  
  79. INLINE
  80. void 
  81. put_word_reg (context, reg, val)
  82.      sim_state_type *context;
  83.      int reg;
  84.      int val;
  85. {
  86.   context->regs[reg].word = val;
  87. }
  88.  
  89. INLINE
  90. SItype get_long_reg (context, reg)
  91.      sim_state_type *context;
  92.      int reg;
  93. {
  94.   USItype lsw = context->regs[reg + 1].word;
  95.   USItype msw = context->regs[reg].word;
  96.  
  97.   return (msw << 16) | lsw;
  98. }
  99.  
  100. #ifdef __GNUC__
  101. INLINE
  102. struct UDIstruct
  103. get_quad_reg (context, reg)
  104.      sim_state_type *context;
  105.      int reg;
  106. {
  107.   UDItype res;
  108.   USItype lsw = get_long_reg (context, reg + 2);
  109.   USItype msw = get_long_reg (context, reg);
  110.  
  111.   res.low = lsw;
  112.   res.high = msw;
  113.   return res;
  114. }
  115.  
  116. #endif
  117.  
  118. INLINE
  119. void 
  120. put_byte_reg (context, reg, val)
  121.      sim_state_type *context;
  122.      int reg;
  123.      int val;
  124. {
  125.   int old = context->regs[reg & 0x7].word;
  126.   if (reg & 0x8)
  127.     {
  128.       old = old & 0xff00 | (val & 0xff);
  129.     }
  130.   else
  131.     {
  132.       old = old & 0x00ff | (val << 8);
  133.     }
  134.   context->regs[reg & 0x7].word = old;      
  135. }
  136.  
  137. INLINE
  138. int 
  139. get_byte_reg (context, reg)
  140.      sim_state_type *context;
  141.      int reg;
  142. {
  143.   if (reg & 0x8)
  144.     return  context->regs[reg & 0x7].word & 0xff;
  145.   else
  146.     return  (context->regs[reg & 0x7].word >> 8) & 0xff;
  147. }
  148.  
  149. INLINE
  150. void 
  151. put_word_mem_da (context, addr, value)
  152.      sim_state_type *context;
  153.      int addr;
  154.      int value;
  155. {
  156.   if (addr & 1)
  157.     {
  158.       context->exception = SIM_BAD_ALIGN;
  159.       addr &= ~1;
  160.     }
  161.   put_byte_mem_da(context, addr, value>>8);
  162.   put_byte_mem_da(context, addr+1, value);
  163. }
  164.  
  165. INLINE unsigned char
  166. get_byte_mem_da (context, addr)
  167.      sim_state_type *context;
  168.      int addr;
  169. {
  170.   return ((unsigned char *) (context->memory))[addr];
  171. }
  172.  
  173. INLINE void
  174. put_byte_mem_da (context, addr, value)
  175.      sim_state_type *context;
  176.      int addr;
  177.      int value;
  178. {
  179.   ((unsigned char *) (context->memory))[addr] = value;
  180. }
  181.  
  182. #if 0
  183. #define get_word_mem_da(context,addr)\
  184.  *((unsigned short*)((char*)((context)->memory)+(addr)))
  185.  
  186. #else
  187. #define get_word_mem_da(context,addr) (get_byte_mem_da(context, addr) << 8) | (get_byte_mem_da(context,addr+1))
  188. #endif
  189.  
  190. #define get_word_reg(context,reg) (context)->regs[reg].word
  191.  
  192. INLINE
  193. SItype
  194. get_long_mem_da (context, addr)
  195.      sim_state_type *context;
  196.      int addr;
  197. {
  198.   USItype lsw = get_word_mem_da(context,addr+2);
  199.   USItype msw =  get_word_mem_da(context, addr);
  200.  
  201.   return (msw << 16) + lsw;
  202. }
  203.  
  204. INLINE
  205. void 
  206. put_long_mem_da (context, addr, value)
  207.      sim_state_type *context;
  208.      int addr;
  209.      int value;
  210. {
  211.   put_word_mem_da(context,addr, value>>16);
  212.   put_word_mem_da(context,addr+2, value);
  213. }
  214.  
  215. INLINE
  216. int 
  217. get_word_mem_ir (context, reg)
  218.      sim_state_type *context;
  219.      int reg;
  220. {
  221.   return get_word_mem_da (context, get_word_reg (context, reg));
  222. }
  223.  
  224. INLINE
  225. void 
  226. put_word_mem_ir (context, reg, value)
  227.      sim_state_type *context;
  228.      int reg;
  229.      int value;
  230. {
  231.  
  232.   put_word_mem_da (context, get_word_reg (context, reg), value);
  233. }
  234.  
  235. INLINE
  236. int 
  237. get_byte_mem_ir (context, reg)
  238.      sim_state_type *context;
  239.      int reg;
  240. {
  241.   return get_byte_mem_da (context, get_word_reg (context, reg));
  242. }
  243.  
  244. INLINE
  245. void 
  246. put_byte_mem_ir (context, reg, value)
  247.      sim_state_type *context;
  248.      int reg;
  249.      int value;
  250. {
  251.   put_byte_mem_da (context, get_word_reg (context, reg), value);
  252. }
  253.  
  254. INLINE
  255. int 
  256. get_long_mem_ir (context, reg)
  257.      sim_state_type *context;
  258.      int reg;
  259. {
  260.   return get_long_mem_da (context, get_word_reg (context, reg));
  261. }
  262.  
  263. INLINE
  264. void 
  265. put_long_mem_ir (context, reg, value)
  266.      sim_state_type *context;
  267.      int reg;
  268.      int value;
  269. {
  270.  
  271.   put_long_mem_da (context, get_word_reg (context, reg), value);
  272. }
  273.  
  274. INLINE
  275. void 
  276. put_long_mem_x (context, base, reg, value)
  277.      sim_state_type *context;
  278.      int base;
  279.      int reg;
  280.      int value;
  281. {
  282.   put_long_mem_da (context, get_word_reg (context, reg) + base, value);
  283. }
  284.  
  285. INLINE
  286. void 
  287. put_word_mem_x (context, base, reg, value)
  288.      sim_state_type *context;
  289.      int base;
  290.      int reg;
  291.      int value;
  292. {
  293.   put_word_mem_da (context, get_word_reg (context, reg) + base, value);
  294. }
  295.  
  296. INLINE
  297. void 
  298. put_byte_mem_x (context, base, reg, value)
  299.      sim_state_type *context;
  300.      int base;
  301.      int reg;
  302.      int value;
  303. {
  304.   put_byte_mem_da (context, get_word_reg (context, reg) + base, value);
  305. }
  306.  
  307. INLINE
  308. int 
  309. get_word_mem_x (context, base, reg)
  310.      sim_state_type *context;
  311.      int base;
  312.      int reg;
  313. {
  314.   return get_word_mem_da (context, base + get_word_reg (context, reg));
  315. }
  316.  
  317. INLINE
  318. int 
  319. get_byte_mem_x (context, base, reg)
  320.      sim_state_type *context;
  321.      int base;
  322.      int reg;
  323. {
  324.   return get_byte_mem_da (context, base + get_word_reg (context, reg));
  325. }
  326.  
  327. INLINE
  328. int 
  329. get_long_mem_x (context, base, reg)
  330.      sim_state_type *context;
  331.      int base;
  332.      int reg;
  333. {
  334.   return get_long_mem_da (context, base + get_word_reg (context, reg));
  335. }
  336.  
  337. static int
  338. is_cond_true (context, c)
  339.      sim_state_type *context;
  340.      int c;
  341. {
  342.   switch (c)
  343.     {
  344.     case T:
  345.       return 1;
  346.     case F:
  347.       return 0;            /* F */
  348.     case LE:
  349.       return (PSW_ZERO | (PSW_SIGN ^ PSW_OVERFLOW)) & 1;    /*LE */
  350.     case GT:
  351.       return (~(PSW_ZERO | (PSW_SIGN ^ PSW_OVERFLOW))) & 1;    /*GT */
  352.     case 0x5:
  353.       return (PSW_SIGN & 1);    /* sign */
  354.     case 0xd:
  355.       return (~(PSW_SIGN)) & 1;    /* not sign */
  356.     case 0x3:
  357.       return ((PSW_CARRY | PSW_ZERO) & 1);    /* ule*/
  358.     case UGT:
  359.       return ((~(PSW_CARRY | PSW_ZERO)) & 1);    /* ugt */
  360.     case 0x4:
  361.       return (PSW_OVERFLOW & 1);/* overflow */
  362.     case 0xc:
  363.       return (~(PSW_OVERFLOW)) & 1;    /* not overflow */
  364.     case LT:
  365.       return (PSW_SIGN ^ PSW_OVERFLOW) & 1;    /* LT */
  366.     case GE:
  367.       return (~(PSW_SIGN ^ PSW_OVERFLOW)) & 1;    /* GE */
  368.     case EQ:
  369.       return (PSW_ZERO) & 1;    /* zero */
  370.     case NE:
  371.       return ((~PSW_ZERO) & 1);    /* not zero */
  372.     case 0x7:
  373.       return (PSW_CARRY) & 1;    /* carry */
  374.     case 0xf:
  375.       return (~PSW_CARRY) & 1;    /* not carry */
  376.     default:
  377.       abort ();
  378.     }
  379. }
  380.  
  381. static
  382. void
  383. makeflags (context, mask)
  384.      sim_state_type *context;
  385.      int mask;
  386. {
  387.  
  388.   PSW_ZERO = (context->dst & mask) == 0;
  389.   PSW_SIGN = (context->dst >> (context->size - 1));
  390.  
  391.   if (context->broken_flags == TST_FLAGS)
  392.     {
  393.       extern char the_parity[];
  394.  
  395.       if (context->size == 8)
  396.     {
  397.       PSW_OVERFLOW = the_parity[context->dst & 0xff];
  398.     }
  399.     }
  400.   else
  401.     {
  402.       /* Overflow is set if both operands have the same sign and the
  403.          result is of different sign.
  404.  
  405.          V =  A==B && R!=B  jumping logic
  406.          (~(A^B))&(R^B)
  407.          V =  (A^B)^(R^B)   boolean
  408.          */
  409.  
  410.       PSW_OVERFLOW =
  411.     ((
  412.        (~(context->srca ^ context->srcb)
  413.         & (context->srca ^ context->dst))
  414.      ) >> (context->size - 1)
  415.     );
  416.  
  417.       if (context->size < 32)
  418.     {
  419.       PSW_CARRY = ((context->dst >> context->size)) & 1;
  420.     }
  421.       else
  422.     {
  423.       /* carry is set when the result is smaller than the first source */
  424.  
  425.       PSW_CARRY = (unsigned) context->dst > (unsigned) context->srca;
  426.     }
  427.     }
  428.   context->broken_flags = 0;
  429. }
  430.  
  431. INLINE
  432. int
  433. COND (context, c)
  434.      sim_state_type *context;
  435.      int c;
  436. {
  437.   if (c == 8)
  438.     return 1;
  439.  
  440.   /* We can calculate what the flags would have been by
  441.      looking at the src and dst and size of the operation */
  442.  
  443.   if (context->broken_flags)
  444.     {
  445.       int slow = 0;
  446.       int size;
  447.       int dst;
  448.       int srca;
  449.       int srcb;
  450.       int mask;
  451.       int ans;
  452.  
  453.       /* see if we can short-cut the nasty flag calcs */
  454.  
  455.       switch (size = context->size)
  456.     {
  457.      default:
  458.       abort();
  459.       return 0;
  460.     case 8:
  461.       srca = (char) (context->srca);
  462.       srcb = (char) (context->srcb);
  463.       dst = (char) (context->dst);
  464.       mask = 0xff;
  465.       break;
  466.     case 16:
  467.       srca = (short) (context->srca);
  468.       srcb = (short) (context->srcb);
  469.       dst = (short) (context->dst);
  470.       mask = 0xffff;
  471.       break;
  472.     case 32:
  473.       srca = (long) (context->srca);
  474.       srcb = (long) (context->srcb);
  475.       dst = (long) (context->dst);
  476.       mask = 0xffffffff;
  477.       break;
  478.     }
  479.  
  480.       switch (c)
  481.     {
  482.     case T:
  483.       return 1;
  484.     case F:
  485.       return 0;
  486.     case EQ:
  487.       return !dst;
  488.     case NE:
  489.       return dst;
  490.     case GT:
  491.       ans = ((dst)) > 0;
  492.       if (slow)
  493.         {
  494.           if (is_cond_true (context, c) != ans)
  495.         abort ();
  496.         }
  497.       return ans;
  498.     case LE:
  499.       ans = ((dst)) <= 0;
  500.       if (slow)
  501.         {
  502.           if (is_cond_true (context, c) != ans)
  503.         abort ();
  504.         }
  505.       return ans;
  506.     case GE:
  507.       ans = ((dst)) >= 0;
  508.       if (slow)
  509.         {
  510.           if (is_cond_true (context, c) != ans)
  511.         abort ();
  512.         }
  513.       return ans;
  514.     case LT:
  515.       ans = ((dst)) < 0;
  516.       if (slow)
  517.         {
  518.           if (is_cond_true (context, c) != ans)
  519.         abort ();
  520.         }
  521.       return ans;
  522.     default:
  523.       break;
  524.     }
  525.  
  526.       /* Can't fake it, we'll have to work out the flags the
  527.          hard way */
  528.  
  529.       makeflags (context, mask);
  530.     }
  531.  
  532.   /* don't know how to fake a test, inspect the flags
  533.      the hard way */
  534.  
  535.   return is_cond_true (context, c);
  536. }
  537.  
  538. INLINE
  539. void 
  540. NORMAL_FLAGS (context, size, dst, srca, srcb)
  541.      sim_state_type *context;
  542.      int size;
  543.      int dst;
  544.      int srca;
  545.      int srcb;
  546. {
  547.   context->srca = srca;
  548.   context->srcb = srcb;
  549.   context->dst = dst;
  550.   context->size = size;
  551.   context->broken_flags = CMP_FLAGS;
  552. }
  553.  
  554. INLINE
  555. void 
  556. TEST_NORMAL_FLAGS (context, size, dst)
  557.      sim_state_type *context;
  558.      int size;
  559.      int dst;
  560. {
  561.   context->dst = dst;
  562.   context->size = size;
  563.   context->broken_flags = TST_FLAGS;
  564. }
  565.  
  566. INLINE
  567. void 
  568. put_ptr_long_reg (context, reg, val)
  569.      sim_state_type *context;
  570.      int reg;
  571.      int val;
  572. {
  573.   context->regs[reg].word = (val >> 8) & 0x7f00;
  574.   context->regs[reg + 1].word = val;
  575. }
  576.  
  577. INLINE
  578. long 
  579. get_ptr_long_reg (context, reg)
  580.      sim_state_type *context;
  581.      int reg;
  582. {
  583.   int val;
  584.  
  585.   val = (context->regs[reg].word << 8) | context->regs[reg + 1].word;
  586.   return val;
  587. }
  588.  
  589. INLINE
  590. long 
  591. get_ptr_long_mem_ir (context, reg)
  592. sim_state_type *context;
  593. int reg;
  594. {
  595.   return sitoptr (get_long_mem_da (context, get_ptr_long_reg (context, reg)));
  596. }
  597.  
  598. INLINE
  599. long 
  600. get_ptr_long_mem_da (context, addr)
  601. sim_state_type *context;
  602. long addr; 
  603. {
  604.   return sitoptr (get_long_mem_da (context, addr));
  605. }
  606.  
  607. INLINE
  608. void 
  609. put_ptr_long_mem_da (context, addr, ptr)
  610. sim_state_type *context;
  611. long addr; 
  612. long ptr;
  613. {
  614.   put_long_mem_da (context, addr, ptrtosi (ptr));
  615.  
  616. }
  617.