do_ptrar.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Sources of the "POINTER ARITHMETIC" group instructions
  3. */
  4. /* $Header$ */
  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. DoADPl2(arg)
  22. long arg;
  23. {
  24. /* ADP f: Add f to pointer on top of stack */
  25. register long l = (L_arg_2() * arg);
  26. register ptr p, t = st_lddp(SP);
  27. LOG(("@R6 DoADPl2(%ld)", l));
  28. spoilFRA();
  29. if (t == 0) {
  30. warning(WNULLPA);
  31. }
  32. l = arg_f(l);
  33. p = adp(t, l);
  34. check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
  35. st_stdp(SP, p);
  36. }
  37. DoADPl4(arg)
  38. long arg;
  39. {
  40. /* ADP f: Add f to pointer on top of stack */
  41. register long l = (L_arg_4() * arg);
  42. register ptr p, t = st_lddp(SP);
  43. LOG(("@R6 DoADPl4(%ld)", l));
  44. spoilFRA();
  45. if (t == 0) {
  46. warning(WNULLPA);
  47. }
  48. l = arg_f(l);
  49. p = adp(t, l);
  50. check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
  51. st_stdp(SP, p);
  52. }
  53. DoADPm(arg)
  54. long arg;
  55. {
  56. /* ADP f: Add f to pointer on top of stack */
  57. register long l = arg_f(arg);
  58. register ptr p, t = st_lddp(SP);
  59. LOG(("@R6 DoADPm(%ld)", l));
  60. spoilFRA();
  61. if (t == 0) {
  62. warning(WNULLPA);
  63. }
  64. l = arg_f(l);
  65. p = adp(t, l);
  66. check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
  67. st_stdp(SP, p);
  68. }
  69. DoADPs(hob, wfac)
  70. long hob;
  71. size wfac;
  72. {
  73. /* ADP f: Add f to pointer on top of stack */
  74. register long l = (S_arg(hob) * wfac);
  75. register ptr p, t = st_lddp(SP);
  76. LOG(("@R6 DoADPs(%ld)", l));
  77. spoilFRA();
  78. if (t == 0) {
  79. warning(WNULLPA);
  80. }
  81. l = arg_f(l);
  82. p = adp(t, l);
  83. check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
  84. st_stdp(SP, p);
  85. }
  86. DoADSl2(arg)
  87. size arg;
  88. {
  89. /* ADS w: Add w-byte value and pointer */
  90. register size l = (L_arg_2() * arg);
  91. register long t = spop(arg_wi(l));
  92. register ptr p, s = st_lddp(SP);
  93. LOG(("@R6 DoADSl2(%ld)", l));
  94. spoilFRA();
  95. t = arg_f(t);
  96. if (s == 0) {
  97. warning(WNULLPA);
  98. }
  99. p = adp(s, t);
  100. check_seg(ptr2seg(s), ptr2seg(p), WSEGADP);
  101. st_stdp(SP, p);
  102. }
  103. DoADSm(arg)
  104. size arg;
  105. {
  106. /* ADS w: Add w-byte value and pointer */
  107. register long t = spop(arg_wi(arg));
  108. register ptr p, s = st_lddp(SP);
  109. LOG(("@R6 DoADSm(%ld)", arg));
  110. spoilFRA();
  111. t = arg_f(t);
  112. if (s == 0) {
  113. warning(WNULLPA);
  114. }
  115. p = adp(s, t);
  116. check_seg(ptr2seg(s), ptr2seg(p), WSEGADP);
  117. st_stdp(SP, p);
  118. }
  119. DoADSz()
  120. {
  121. /* ADS w: Add w-byte value and pointer */
  122. register size l = upop(wsize);
  123. register long t = spop(arg_wi(l));
  124. register ptr p, s = st_lddp(SP);
  125. LOG(("@R6 DoADSz(%ld)", l));
  126. spoilFRA();
  127. t = arg_f(t);
  128. if (s == 0) {
  129. warning(WNULLPA);
  130. }
  131. p = adp(s, t);
  132. check_seg(ptr2seg(s), ptr2seg(p), WSEGADP);
  133. st_stdp(SP, p);
  134. }
  135. DoSBSl2(arg)
  136. size arg;
  137. {
  138. /* SBS w: Subtract pointers in same fragment and push diff as size w integer */
  139. register size l = (L_arg_2() * arg);
  140. register ptr t = st_lddp(SP);
  141. register ptr s = st_lddp(SP + psize);
  142. register long w;
  143. LOG(("@R6 DoSBSl2(%ld)", l));
  144. spoilFRA();
  145. l = arg_wi(l);
  146. check_seg(ptr2seg(t), ptr2seg(s), WSEGSBS);
  147. w = sbs(t, s);
  148. if (must_test && !(IgnMask&BIT(EIOVFL))) {
  149. if (l == 2 && (w < I_MINS2 || w > I_MAXS2))
  150. trap(EIOVFL);
  151. }
  152. dppop();
  153. dppop();
  154. npush(w, l);
  155. }
  156. DoSBSz()
  157. {
  158. /* SBS w: Subtract pointers in same fragment and push diff as size w integer */
  159. register size l = upop(wsize);
  160. register ptr t = st_lddp(SP);
  161. register ptr s = st_lddp(SP + psize);
  162. register long w;
  163. LOG(("@R6 DoSBSz(%ld)", l));
  164. spoilFRA();
  165. l = arg_wi(l);
  166. check_seg(ptr2seg(t), ptr2seg(s), WSEGSBS);
  167. w = sbs(t, s);
  168. if (must_test && !(IgnMask&BIT(EIOVFL))) {
  169. if (l == 2 && (w < I_MINS2 || w > I_MAXS2))
  170. trap(EIOVFL);
  171. }
  172. dppop();
  173. dppop();
  174. npush(w, l);
  175. }