do_misc.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. /*
  2. * Sources of the "MISCELLANEOUS" group instructions
  3. */
  4. /* $Header$ */
  5. #include <em_abs.h>
  6. #include "logging.h"
  7. #include "global.h"
  8. #include "log.h"
  9. #include "trap.h"
  10. #include "warn.h"
  11. #include "mem.h"
  12. #include "memdirect.h"
  13. #include "shadow.h"
  14. #include "text.h"
  15. #include "read.h"
  16. #include "fra.h"
  17. #include "rsb.h"
  18. #include "linfil.h"
  19. extern int running; /* from main.c */
  20. /* Two useful but unofficial registers */
  21. long LIN;
  22. ptr FIL;
  23. PRIVATE index_jump(), range_check(), search_jump();
  24. PRIVATE gto();
  25. #define asp(l) newSP(SP + arg_f(l))
  26. DoASPl2(arg)
  27. long arg;
  28. {
  29. /* ASP f: Adjust the stack pointer by f */
  30. register long l = (L_arg_2() * arg);
  31. LOG(("@M6 DoASPl2(%ld)", l));
  32. asp(l);
  33. }
  34. DoASPl4(arg)
  35. long arg;
  36. {
  37. /* ASP f: Adjust the stack pointer by f */
  38. register long l = (L_arg_4() * arg);
  39. LOG(("@M6 DoASPl4(%ld)", l));
  40. asp(l);
  41. }
  42. DoASPm(arg)
  43. long arg;
  44. {
  45. /* ASP f: Adjust the stack pointer by f */
  46. register long l = arg;
  47. LOG(("@M6 DoASPm(%ld)", l));
  48. asp(l);
  49. }
  50. DoASPs(hob, wfac)
  51. long hob;
  52. size wfac;
  53. {
  54. /* ASP f: Adjust the stack pointer by f */
  55. register long l = (S_arg(hob) * wfac);
  56. LOG(("@M6 DoASPs(%ld)", l));
  57. asp(l);
  58. }
  59. DoASSl2(arg)
  60. size arg;
  61. {
  62. /* ASS w: Adjust the stack pointer by w-byte integer */
  63. register size l = (L_arg_2() * arg);
  64. LOG(("@M6 DoASSl2(%ld)", l));
  65. spoilFRA();
  66. l = spop(arg_wi(l));
  67. asp(l);
  68. }
  69. DoASSz()
  70. {
  71. /* ASS w: Adjust the stack pointer by w-byte integer */
  72. register size l = upop(wsize);
  73. LOG(("@M6 DoASSz(%ld)", l));
  74. spoilFRA();
  75. l = spop(arg_wi(l));
  76. asp(l);
  77. }
  78. #define block_move(a1,a2,n) \
  79. if (in_stack(a1)) { \
  80. if (in_stack(a2)) st_mvs(a1, a2, n); \
  81. else st_mvd(a1, a2, n); } \
  82. else { if (in_stack(a2)) dt_mvs(a1, a2, n); \
  83. else dt_mvd(a1, a2, n); }
  84. DoBLMl2(arg)
  85. size arg;
  86. {
  87. /* BLM z: Block move z bytes; first pop destination addr, then source addr */
  88. register size l = (L_arg_2() * arg);
  89. register ptr dp1, dp2; /* Destination Pointers */
  90. LOG(("@M6 DoBLMl2(%ld)", l));
  91. spoilFRA();
  92. dp1 = dppop();
  93. dp2 = dppop();
  94. block_move(dp1, dp2, arg_z(l));
  95. }
  96. DoBLMl4(arg)
  97. size arg;
  98. {
  99. /* BLM z: Block move z bytes; first pop destination addr, then source addr */
  100. register size l = (L_arg_4() * arg);
  101. register ptr dp1, dp2; /* Destination Pointer */
  102. LOG(("@M6 DoBLMl4(%ld)", l));
  103. spoilFRA();
  104. dp1 = dppop();
  105. dp2 = dppop();
  106. block_move(dp1, dp2, arg_z(l));
  107. }
  108. DoBLMs(hob, wfac)
  109. long hob;
  110. size wfac;
  111. {
  112. /* BLM z: Block move z bytes; first pop destination addr, then source addr */
  113. register size l = (S_arg(hob) * wfac);
  114. register ptr dp1, dp2; /* Destination Pointer */
  115. LOG(("@M6 DoBLMs(%ld)", l));
  116. spoilFRA();
  117. dp1 = dppop();
  118. dp2 = dppop();
  119. block_move(dp1, dp2, arg_z(l));
  120. }
  121. DoBLSl2(arg)
  122. size arg;
  123. {
  124. /* BLS w: Block move, size is in w-byte integer on top of stack */
  125. register size l = (L_arg_2() * arg);
  126. register ptr dp1, dp2;
  127. LOG(("@M6 DoBLSl2(%ld)", l));
  128. spoilFRA();
  129. l = upop(arg_wi(l));
  130. dp1 = dppop();
  131. dp2 = dppop();
  132. block_move(dp1, dp2, arg_z(l));
  133. }
  134. DoBLSz()
  135. {
  136. /* BLS w: Block move, size is in w-byte integer on top of stack */
  137. register size l = upop(wsize);
  138. register ptr dp1, dp2;
  139. LOG(("@M6 DoBLSz(%ld)", l));
  140. spoilFRA();
  141. l = upop(arg_wi(l));
  142. dp1 = dppop();
  143. dp2 = dppop();
  144. block_move(dp1, dp2, arg_z(l));
  145. }
  146. DoCSAl2(arg)
  147. size arg;
  148. {
  149. /* CSA w: Case jump; address of jump table at top of stack */
  150. register size l = (L_arg_2() * arg);
  151. LOG(("@M6 DoCSAl2(%ld)", l));
  152. spoilFRA();
  153. index_jump(arg_wi(l));
  154. }
  155. DoCSAm(arg)
  156. size arg;
  157. {
  158. /* CSA w: Case jump; address of jump table at top of stack */
  159. LOG(("@M6 DoCSAm(%ld)", arg));
  160. spoilFRA();
  161. index_jump(arg_wi(arg));
  162. }
  163. DoCSAz()
  164. {
  165. /* CSA w: Case jump; address of jump table at top of stack */
  166. register size l = upop(wsize);
  167. LOG(("@M6 DoCSAz(%ld)", l));
  168. spoilFRA();
  169. index_jump(arg_wi(l));
  170. }
  171. DoCSBl2(arg)
  172. size arg;
  173. {
  174. /* CSB w: Table lookup jump; address of jump table at top of stack */
  175. register size l = (L_arg_2() * arg);
  176. LOG(("@M6 DoCSBl2(%ld)", l));
  177. spoilFRA();
  178. search_jump(arg_wi(l));
  179. }
  180. DoCSBm(arg)
  181. size arg;
  182. {
  183. /* CSB w: Table lookup jump; address of jump table at top of stack */
  184. LOG(("@M6 DoCSBm(%ld)", arg));
  185. spoilFRA();
  186. search_jump(arg_wi(arg));
  187. }
  188. DoCSBz()
  189. {
  190. /* CSB w: Table lookup jump; address of jump table at top of stack */
  191. register size l = upop(wsize);
  192. LOG(("@M6 DoCSBz(%ld)", l));
  193. spoilFRA();
  194. search_jump(arg_wi(l));
  195. }
  196. DoDCHz()
  197. {
  198. /* DCH -: Follow dynamic chain, convert LB to LB of caller */
  199. register ptr lb;
  200. LOG(("@M6 DoDCHz()"));
  201. spoilFRA();
  202. lb = dppop();
  203. if (!is_LB(lb)) {
  204. wtrap(WDCHBADLB, ESTACK);
  205. }
  206. dppush(st_lddp(lb + rsb_LB));
  207. }
  208. DoDUPl2(arg)
  209. size arg;
  210. {
  211. /* DUP s: Duplicate top s bytes */
  212. register size l = (L_arg_2() * arg);
  213. register ptr oldSP = SP;
  214. LOG(("@M6 DoDUPl2(%ld)", l));
  215. spoilFRA();
  216. st_inc(arg_s(l));
  217. st_mvs(SP, oldSP, l);
  218. }
  219. DoDUPm(arg)
  220. size arg;
  221. {
  222. /* DUP s: Duplicate top s bytes */
  223. register ptr oldSP = SP;
  224. LOG(("@M6 DoDUPm(%ld)", arg));
  225. spoilFRA();
  226. st_inc(arg_s(arg));
  227. st_mvs(SP, oldSP, arg);
  228. }
  229. DoDUSl2(arg)
  230. size arg;
  231. {
  232. /* DUS w: Duplicate top w bytes */
  233. register size l = (L_arg_2() * arg);
  234. register ptr oldSP;
  235. LOG(("@M6 DoDUSl2(%ld)", l));
  236. spoilFRA();
  237. l = upop(arg_wi(l));
  238. oldSP = SP;
  239. st_inc(arg_s(l));
  240. st_mvs(SP, oldSP, l);
  241. }
  242. DoDUSz()
  243. {
  244. /* DUS w: Duplicate top w bytes */
  245. register size l = upop(wsize);
  246. register ptr oldSP;
  247. LOG(("@M6 DoDUSz(%ld)", l));
  248. spoilFRA();
  249. l = upop(arg_wi(l));
  250. oldSP = SP;
  251. st_inc(arg_s(l));
  252. st_mvs(SP, oldSP, l);
  253. }
  254. DoEXGl2(arg)
  255. size arg;
  256. {
  257. /* EXG w: Exchange top w bytes */
  258. register size l = (L_arg_2() * arg);
  259. register ptr oldSP = SP;
  260. LOG(("@M6 DoEXGl2(%ld)", l));
  261. spoilFRA();
  262. st_inc(arg_w(l));
  263. st_mvs(SP, oldSP, l);
  264. st_mvs(oldSP, oldSP + l, l);
  265. st_mvs(oldSP + l, SP, l);
  266. st_dec(l);
  267. }
  268. DoEXGs(hob, wfac)
  269. long hob;
  270. size wfac;
  271. {
  272. /* EXG w: Exchange top w bytes */
  273. register size l = (S_arg(hob) * wfac);
  274. register ptr oldSP = SP;
  275. LOG(("@M6 DoEXGs(%ld)", l));
  276. spoilFRA();
  277. st_inc(arg_w(l));
  278. st_mvs(SP, oldSP, l);
  279. st_mvs(oldSP, oldSP + l, l);
  280. st_mvs(oldSP + l, SP, l);
  281. st_dec(l);
  282. }
  283. DoEXGz()
  284. {
  285. /* EXG w: Exchange top w bytes */
  286. register size l = upop(wsize);
  287. register ptr oldSP = SP;
  288. LOG(("@M6 DoEXGz(%ld)", l));
  289. spoilFRA();
  290. st_inc(arg_w(l));
  291. st_mvs(SP, oldSP, l);
  292. st_mvs(oldSP, oldSP + l, l);
  293. st_mvs(oldSP + l, SP, l);
  294. st_dec(l);
  295. }
  296. DoFILu(arg)
  297. long arg;
  298. {
  299. /* FIL g: File name (external 4 := g) */
  300. register ptr p = i2p(U_arg() * arg);
  301. LOG(("@M6 DoFILu(%lu)", p));
  302. spoilFRA();
  303. if (p > HB) {
  304. wtrap(WILLFIL, EILLINS);
  305. }
  306. putFIL(arg_g(p));
  307. }
  308. DoFILl4(arg)
  309. long arg;
  310. {
  311. /* FIL g: File name (external 4 := g) */
  312. register ptr p = i2p(L_arg_4() * arg);
  313. LOG(("@M6 DoFILl4(%lu)", p));
  314. spoilFRA();
  315. if (p > HB) {
  316. wtrap(WILLFIL, EILLINS);
  317. }
  318. putFIL(arg_g(p));
  319. }
  320. DoGTOu(arg)
  321. long arg;
  322. {
  323. /* GTO g: Non-local goto, descriptor at g */
  324. register ptr p = i2p(U_arg() * arg);
  325. LOG(("@M6 DoGTOu(%lu)", p));
  326. gto(arg_gto(p));
  327. }
  328. DoGTOl4(arg)
  329. long arg;
  330. {
  331. /* GTO g: Non-local goto, descriptor at g */
  332. register ptr p = i2p(L_arg_4() * arg);
  333. LOG(("@M6 DoGTOl4(%lu)", p));
  334. gto(arg_gto(p));
  335. }
  336. DoLIMz()
  337. {
  338. /* LIM -: Load 16 bit ignore mask */
  339. LOG(("@M6 DoLIMz()"));
  340. spoilFRA();
  341. npush(IgnMask, wsize);
  342. }
  343. DoLINl2(arg)
  344. long arg;
  345. {
  346. /* LIN n: Line number (external 0 := n) */
  347. register unsigned long l = (L_arg_2() * arg);
  348. LOG(("@M6 DoLINl2(%lu)", l));
  349. spoilFRA();
  350. putLIN((long) arg_lin(l));
  351. }
  352. DoLINl4(arg)
  353. long arg;
  354. {
  355. /* LIN n: Line number (external 0 := n) */
  356. register unsigned long l = (L_arg_4() * arg);
  357. LOG(("@M6 DoLINl4(%lu)", l));
  358. spoilFRA();
  359. putLIN((long) arg_lin(l));
  360. }
  361. DoLINs(hob, wfac)
  362. long hob;
  363. size wfac;
  364. {
  365. /* LIN n: Line number (external 0 := n) */
  366. register unsigned long l = (S_arg(hob) * wfac);
  367. LOG(("@M6 DoLINs(%lu)", l));
  368. spoilFRA();
  369. putLIN((long) arg_lin(l));
  370. }
  371. DoLNIz()
  372. {
  373. /* LNI -: Line number increment */
  374. LOG(("@M6 DoLNIz()"));
  375. spoilFRA();
  376. putLIN((long)getLIN() + 1);
  377. }
  378. DoLORs(hob, wfac)
  379. long hob;
  380. size wfac;
  381. {
  382. /* LOR r: Load register (0=LB, 1=SP, 2=HP) */
  383. register long l = (S_arg(hob) * wfac);
  384. LOG(("@M6 DoLORs(%ld)", l));
  385. spoilFRA();
  386. switch ((int) arg_r(l)) {
  387. case 0:
  388. dppush(LB);
  389. break;
  390. case 1:
  391. dppush(SP);
  392. break;
  393. case 2:
  394. dppush(HP);
  395. break;
  396. }
  397. }
  398. DoLPBz()
  399. {
  400. /* LPB -: Convert local base to argument base */
  401. register ptr lb;
  402. LOG(("@M6 DoLPBz()"));
  403. spoilFRA();
  404. lb = dppop();
  405. if (!is_LB(lb)) {
  406. wtrap(WLPBBADLB, ESTACK);
  407. }
  408. dppush(lb + rsbsize);
  409. }
  410. DoMONz()
  411. {
  412. /* MON -: Monitor call */
  413. LOG(("@M6 DoMONz()"));
  414. spoilFRA();
  415. moncall();
  416. }
  417. DoNOPz()
  418. {
  419. /* NOP -: No operation */
  420. LOG(("@M6 DoNOPz()"));
  421. spoilFRA();
  422. message("NOP instruction");
  423. }
  424. DoRCKl2(arg)
  425. size arg;
  426. {
  427. /* RCK w: Range check; trap on error */
  428. register size l = (L_arg_2() * arg);
  429. LOG(("@M6 DoRCKl2(%ld)", l));
  430. spoilFRA();
  431. range_check(arg_wi(l));
  432. }
  433. DoRCKm(arg)
  434. size arg;
  435. {
  436. /* RCK w: Range check; trap on error */
  437. LOG(("@M6 DoRCKm(%ld)", arg));
  438. spoilFRA();
  439. range_check(arg_wi(arg));
  440. }
  441. DoRCKz()
  442. {
  443. /* RCK w: Range check; trap on error */
  444. register size l = upop(wsize);
  445. LOG(("@M6 DoRCKz(%ld)", l));
  446. spoilFRA();
  447. range_check(arg_wi(l));
  448. }
  449. DoRTTz()
  450. {
  451. /* RTT -: Return from trap */
  452. LOG(("@M6 DoRTTz()"));
  453. switch (poprsb(1)) {
  454. case RSB_STP:
  455. warning(WRTTEMPTY);
  456. running = 0; /* stop the machine */
  457. return;
  458. case RSB_CAL:
  459. warning(WRTTCALL);
  460. return;
  461. case RSB_RTT:
  462. /* OK */
  463. break;
  464. case RSB_NRT:
  465. warning(WRTTNRTT);
  466. running = 0; /* stop the machine */
  467. return;
  468. default:
  469. warning(WRTTBAD);
  470. return;
  471. }
  472. /* pop the trap number */
  473. upop(wsize);
  474. /* restore the Function Return Area */
  475. FRA_def = upop(wsize);
  476. FRASize = upop(wsize);
  477. popFRA(FRASize);
  478. }
  479. DoSIGz()
  480. {
  481. /* SIG -: Trap errors to proc identifier on top of stack, \-2 resets default */
  482. register long tpi = spop(psize);
  483. LOG(("@M6 DoSIGz()"));
  484. spoilFRA();
  485. npush(TrapPI, psize);
  486. if (tpi == -2) {
  487. OnTrap = TR_HALT;
  488. TrapPI = 0;
  489. }
  490. else {
  491. tpi = arg_p(tpi); /* do not test earlier! */
  492. OnTrap = TR_TRAP;
  493. TrapPI = tpi;
  494. }
  495. }
  496. DoSIMz()
  497. {
  498. /* SIM -: Store 16 bit ignore mask */
  499. LOG(("@M6 DoSIMz()"));
  500. spoilFRA();
  501. IgnMask = (upop(wsize) | PreIgnMask) & MASK2;
  502. }
  503. DoSTRs(hob, wfac)
  504. long hob;
  505. size wfac;
  506. {
  507. /* STR r: Store register (0=LB, 1=SP, 2=HP) */
  508. register long l = (S_arg(hob) * wfac);
  509. LOG(("@M6 DoSTRs(%ld)", l));
  510. spoilFRA();
  511. switch ((int) arg_r(l)) {
  512. case 0:
  513. newLB(dppop());
  514. pop_frames();
  515. break;
  516. case 1:
  517. newSP(dppop());
  518. break;
  519. case 2:
  520. newHP(dppop());
  521. break;
  522. }
  523. }
  524. DoTRPz()
  525. {
  526. /* TRP -: Cause trap to occur (Error number on stack) */
  527. register unsigned int tr = (unsigned int)upop(wsize);
  528. LOG(("@M6 DoTRPz()"));
  529. spoilFRA();
  530. if (tr > 15 || !(IgnMask&BIT(tr))) {
  531. wtrap(WTRP, (int)tr);
  532. }
  533. }
  534. /* Service routines */
  535. PRIVATE gto(p)
  536. ptr p;
  537. {
  538. register ptr old_LB = LB;
  539. register ptr new_PC = dt_ldip(p);
  540. register ptr new_SP = dt_lddp(p + psize);
  541. register ptr new_LB = dt_lddp(p + (2 * psize));
  542. while (old_LB < new_LB) {
  543. PI = st_lds(old_LB + rsb_PI, psize);
  544. old_LB = st_lddp(old_LB + rsb_LB);
  545. }
  546. if (old_LB != new_LB) {
  547. wtrap(WGTORSB, EBADGTO);
  548. }
  549. newLB(new_LB);
  550. pop_frames();
  551. newSP(new_SP);
  552. newPC(new_PC);
  553. }
  554. /*
  555. The LIN and FIL routines.
  556. The values of LIN and FIL are kept in EM machine registers
  557. (variables LIN and FIL) and in the data space.
  558. */
  559. putLIN(lin)
  560. long lin;
  561. {
  562. dt_unprot(i2p(LINO_AD), (long)LINSIZE);
  563. dt_stn(i2p(LINO_AD), lin, (long)LINSIZE);
  564. LIN = lin;
  565. dt_prot(i2p(LINO_AD), (long)LINSIZE);
  566. }
  567. putFIL(fil)
  568. ptr fil;
  569. {
  570. dt_unprot(i2p(FILN_AD), psize);
  571. dt_stdp(i2p(FILN_AD), fil);
  572. FIL = fil;
  573. dt_prot(i2p(FILN_AD), psize);
  574. }
  575. /********************************************************
  576. * Case jump by indexing *
  577. * *
  578. * 1. pop case descriptor pointer. *
  579. * 2. pop table index. *
  580. * 3. Calculate (table index) - (lower bound). *
  581. * 4. Check if in range. *
  582. * 5. If in range: load Program Counter value. *
  583. * 6. Else: load default value. *
  584. ********************************************************/
  585. PRIVATE index_jump(nbytes)
  586. size nbytes;
  587. {
  588. register ptr cdp = dppop(); /* Case Descriptor Pointer */
  589. register long t_index = /* Table INDEX */
  590. spop(nbytes) - mem_lds(cdp + psize, wsize);
  591. register ptr nPC; /* New Program Counter */
  592. if (t_index >= 0 && t_index <= mem_lds(cdp + wsize + psize, wsize)) {
  593. nPC = mem_ldip(cdp + (2 * wsize) + ((t_index + 1) * psize));
  594. }
  595. else if ((nPC = mem_ldip(cdp)) == 0) {
  596. trap(ECASE);
  597. }
  598. newPC(nPC);
  599. }
  600. /********************************************************
  601. * Case jump by table search *
  602. * *
  603. * 1. pop case descriptor pointer. *
  604. * 2. pop search value. *
  605. * 3. Load number of table entries. *
  606. * 4. Check if search value in table. *
  607. * 5. If found: load Program Counter value. *
  608. * 6. Else: load default value. *
  609. ********************************************************/
  610. PRIVATE search_jump(nbytes)
  611. size nbytes;
  612. {
  613. register ptr cdp = dppop(); /* Case Descriptor Pointer */
  614. register long sv = spop(nbytes);/* Search Value */
  615. register long nt = /* Number of Table-entries */
  616. mem_lds(cdp + psize, wsize);
  617. register ptr nPC; /* New Program Counter */
  618. while (--nt >= 0) {
  619. if (sv == mem_lds(cdp + (nt+1) * (wsize+psize), wsize)) {
  620. nPC = mem_ldip(cdp + wsize + (nt+1)*(wsize+psize));
  621. if (nPC == 0)
  622. trap(ECASE);
  623. newPC(nPC);
  624. return;
  625. }
  626. }
  627. nPC = mem_ldip(cdp);
  628. if (nPC == 0)
  629. trap(ECASE);
  630. newPC(nPC);
  631. }
  632. /********************************************************
  633. * Range check *
  634. * *
  635. * 1. Load range descriptor. *
  636. * 2. Check against lower and upper bound. *
  637. * 3. Generate trap if necessary. *
  638. * 4. DON'T remove integer. *
  639. ********************************************************/
  640. PRIVATE range_check(nbytes)
  641. size nbytes;
  642. {
  643. register ptr rdp = dppop(); /* Range check Descriptor Pointer */
  644. register long cv = /* Check Value */
  645. st_lds(SP, nbytes);
  646. if (must_test && !(IgnMask&BIT(ERANGE))) {
  647. if ( cv < mem_lds(rdp, wsize)
  648. || cv > mem_lds(rdp + wsize, wsize)
  649. ) {
  650. trap(ERANGE);
  651. }
  652. }
  653. }