do_ptrar.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * Sources of the "POINTER ARITHMETIC" group instructions
  3. */
  4. /* $Id$ */
  5. #include <em_abs.h>
  6. #include "segcheck.h"
  7. #include "global.h"
  8. #include "log.h"
  9. #include "mem.h"
  10. #include "trap.h"
  11. #include "warn.h"
  12. #include "text.h"
  13. #include "fra.h"
  14. #define adp(p,w) ((p) + (w))
  15. #define sbs(t,s) ((s) - (t))
  16. #ifdef SEGCHECK
  17. #define check_seg(s1,s2,w) if (s1 != s2) { warning(w); }
  18. #else
  19. #define check_seg(s1,s2,w)
  20. #endif /* SEGCHECK */
  21. DoADP(l)
  22. register long l;
  23. {
  24. /* ADP f: Add f to pointer on top of stack */
  25. register ptr p, t = st_lddp(SP);
  26. LOG(("@R6 DoADP(%ld)", l));
  27. spoilFRA();
  28. if (t == 0) {
  29. warning(WNULLPA);
  30. }
  31. l = arg_f(l);
  32. p = adp(t, l);
  33. check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
  34. st_stdp(SP, p);
  35. }
  36. DoADS(l)
  37. register size l;
  38. {
  39. /* ADS w: Add w-byte value and pointer */
  40. register long t = spop(arg_wi(l));
  41. register ptr p, s = st_lddp(SP);
  42. LOG(("@R6 DoADS(%ld)", l));
  43. spoilFRA();
  44. t = arg_f(t);
  45. if (s == 0) {
  46. warning(WNULLPA);
  47. }
  48. p = adp(s, t);
  49. check_seg(ptr2seg(s), ptr2seg(p), WSEGADP);
  50. st_stdp(SP, p);
  51. }
  52. DoSBS(l)
  53. register size l;
  54. {
  55. /* SBS w: Subtract pointers in same fragment and push diff as size w integer */
  56. register ptr t = st_lddp(SP);
  57. register ptr s = st_lddp(SP + psize);
  58. register long w;
  59. LOG(("@R6 DoSBS(%ld)", l));
  60. spoilFRA();
  61. l = arg_wi(l);
  62. check_seg(ptr2seg(t), ptr2seg(s), WSEGSBS);
  63. w = sbs(t, s);
  64. if (must_test && !(IgnMask&BIT(EIOVFL))) {
  65. if (l == 2 && (w < I_MINS2 || w > I_MAXS2))
  66. trap(EIOVFL);
  67. }
  68. dppop();
  69. dppop();
  70. npush(w, l);
  71. }