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