123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- * Sources of the "POINTER ARITHMETIC" group instructions
- */
- /* $Header$ */
- #include <em_abs.h>
- #include "segcheck.h"
- #include "global.h"
- #include "log.h"
- #include "mem.h"
- #include "trap.h"
- #include "warn.h"
- #include "text.h"
- #include "fra.h"
- #define adp(p,w) ((p) + (w))
- #define sbs(t,s) ((s) - (t))
- #ifdef SEGCHECK
- #define check_seg(s1,s2,w) if (s1 != s2) { warning(w); }
- #else
- #define check_seg(s1,s2,w)
- #endif SEGCHECK
- DoADPl2(arg)
- long arg;
- {
- /* ADP f: Add f to pointer on top of stack */
- register long l = (L_arg_2() * arg);
- register ptr p, t = st_lddp(SP);
- LOG(("@R6 DoADPl2(%ld)", l));
- spoilFRA();
- if (t == 0) {
- warning(WNULLPA);
- }
- l = arg_f(l);
- p = adp(t, l);
- check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
- st_stdp(SP, p);
- }
- DoADPl4(arg)
- long arg;
- {
- /* ADP f: Add f to pointer on top of stack */
- register long l = (L_arg_4() * arg);
- register ptr p, t = st_lddp(SP);
- LOG(("@R6 DoADPl4(%ld)", l));
- spoilFRA();
- if (t == 0) {
- warning(WNULLPA);
- }
- l = arg_f(l);
- p = adp(t, l);
- check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
- st_stdp(SP, p);
- }
- DoADPm(arg)
- long arg;
- {
- /* ADP f: Add f to pointer on top of stack */
- register long l = arg_f(arg);
- register ptr p, t = st_lddp(SP);
- LOG(("@R6 DoADPm(%ld)", l));
- spoilFRA();
- if (t == 0) {
- warning(WNULLPA);
- }
- l = arg_f(l);
- p = adp(t, l);
- check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
- st_stdp(SP, p);
- }
- DoADPs(hob, wfac)
- long hob;
- size wfac;
- {
- /* ADP f: Add f to pointer on top of stack */
- register long l = (S_arg(hob) * wfac);
- register ptr p, t = st_lddp(SP);
- LOG(("@R6 DoADPs(%ld)", l));
- spoilFRA();
- if (t == 0) {
- warning(WNULLPA);
- }
- l = arg_f(l);
- p = adp(t, l);
- check_seg(ptr2seg(t), ptr2seg(p), WSEGADP);
- st_stdp(SP, p);
- }
- DoADSl2(arg)
- size arg;
- {
- /* ADS w: Add w-byte value and pointer */
- register size l = (L_arg_2() * arg);
- register long t = spop(arg_wi(l));
- register ptr p, s = st_lddp(SP);
- LOG(("@R6 DoADSl2(%ld)", l));
- spoilFRA();
- t = arg_f(t);
- if (s == 0) {
- warning(WNULLPA);
- }
- p = adp(s, t);
- check_seg(ptr2seg(s), ptr2seg(p), WSEGADP);
- st_stdp(SP, p);
- }
- DoADSm(arg)
- size arg;
- {
- /* ADS w: Add w-byte value and pointer */
- register long t = spop(arg_wi(arg));
- register ptr p, s = st_lddp(SP);
- LOG(("@R6 DoADSm(%ld)", arg));
- spoilFRA();
- t = arg_f(t);
- if (s == 0) {
- warning(WNULLPA);
- }
- p = adp(s, t);
- check_seg(ptr2seg(s), ptr2seg(p), WSEGADP);
- st_stdp(SP, p);
- }
- DoADSz()
- {
- /* ADS w: Add w-byte value and pointer */
- register size l = upop(wsize);
- register long t = spop(arg_wi(l));
- register ptr p, s = st_lddp(SP);
- LOG(("@R6 DoADSz(%ld)", l));
- spoilFRA();
- t = arg_f(t);
- if (s == 0) {
- warning(WNULLPA);
- }
- p = adp(s, t);
- check_seg(ptr2seg(s), ptr2seg(p), WSEGADP);
- st_stdp(SP, p);
- }
- DoSBSl2(arg)
- size arg;
- {
- /* SBS w: Subtract pointers in same fragment and push diff as size w integer */
- register size l = (L_arg_2() * arg);
- register ptr t = st_lddp(SP);
- register ptr s = st_lddp(SP + psize);
- register long w;
- LOG(("@R6 DoSBSl2(%ld)", l));
- spoilFRA();
- l = arg_wi(l);
- check_seg(ptr2seg(t), ptr2seg(s), WSEGSBS);
- w = sbs(t, s);
- if (must_test && !(IgnMask&BIT(EIOVFL))) {
- if (l == 2 && (w < I_MINS2 || w > I_MAXS2))
- trap(EIOVFL);
- }
- dppop();
- dppop();
- npush(w, l);
- }
- DoSBSz()
- {
- /* SBS w: Subtract pointers in same fragment and push diff as size w integer */
- register size l = upop(wsize);
- register ptr t = st_lddp(SP);
- register ptr s = st_lddp(SP + psize);
- register long w;
- LOG(("@R6 DoSBSz(%ld)", l));
- spoilFRA();
- l = arg_wi(l);
- check_seg(ptr2seg(t), ptr2seg(s), WSEGSBS);
- w = sbs(t, s);
- if (must_test && !(IgnMask&BIT(EIOVFL))) {
- if (l == 2 && (w < I_MINS2 || w > I_MAXS2))
- trap(EIOVFL);
- }
- dppop();
- dppop();
- npush(w, l);
- }
|