123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- /*
- * Sources of the "UNSIGNED ARITHMETIC" group instructions
- */
- /* $Header$ */
- #include <em_abs.h>
- #include "logging.h"
- #include "global.h"
- #include "log.h"
- #include "mem.h"
- #include "trap.h"
- #include "warn.h"
- #include "text.h"
- #include "fra.h"
- /************************************************************************
- * No checking is performed, except for division by zero. *
- * The operands popped from the stack are put in unsigned *
- * longs. Now the required operation can be performed *
- * immediately. Whether the wordsize is two or four bytes *
- * doesn't matter. Alas, arithmetic is performed modulo *
- * the highest unsigned number for the given size plus 1. *
- ************************************************************************/
- #ifdef LOGGING
- extern int must_test;
- #endif LOGGING
- #define adu(w1,w2) (unsigned long)(w1 + w2)
- #define sbu(w1,w2) (unsigned long)(w1 - w2)
- #define mlu(w1,w2) (unsigned long)(w1 * w2)
- PRIVATE unsigned long dvu(), rmu(), slu(), sru();
- DoADUl2(arg)
- size arg;
- {
- /* ADU w: Addition */
- register size l = (L_arg_2() * arg);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoADUl2(%ld)", l));
- spoilFRA();
- npush((long) adu(upop(l), t), l);
- }
- DoADUz()
- {
- /* ADU w: Addition */
- register size l = upop(wsize);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoADUz(%ld)", l));
- spoilFRA();
- npush((long) adu(upop(l), t), l);
- }
- DoSBUl2(arg)
- size arg;
- {
- /* SBU w: Subtraction */
- register size l = (L_arg_2() * arg);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoSBUl2(%ld)", l));
- spoilFRA();
- npush((long) sbu(upop(l), t), l);
- }
- DoSBUz()
- {
- /* SBU w: Subtraction */
- register size l = upop(wsize);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoSBUz(%ld)", l));
- spoilFRA();
- npush((long) sbu(upop(l), t), l);
- }
- DoMLUl2(arg)
- size arg;
- {
- /* MLU w: Multiplication */
- register size l = (L_arg_2() * arg);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoMLUl2(%ld)", l));
- spoilFRA();
- npush((long) mlu(upop(l), t), l);
- }
- DoMLUz()
- {
- /* MLU w: Multiplication */
- register size l = upop(wsize);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoMLUz(%ld)", l));
- spoilFRA();
- npush((long) mlu(upop(l), t), l);
- }
- DoDVUl2(arg)
- size arg;
- {
- /* DVU w: Division */
- register size l = (L_arg_2() * arg);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoDVUl2(%ld)", l));
- spoilFRA();
- npush((long) dvu(upop(l), t), l);
- }
- DoDVUz()
- {
- /* DVU w: Division */
- register size l = upop(wsize);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoDVUz(%ld)", l));
- spoilFRA();
- npush((long) dvu(upop(l), t), l);
- }
- DoRMUl2(arg)
- size arg;
- {
- /* RMU w: Remainder */
- register size l = (L_arg_2() * arg);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoRMUl2(%ld)", l));
- spoilFRA();
- npush((long) rmu(upop(l), t), l);
- }
- DoRMUz()
- {
- /* RMU w: Remainder */
- register size l = upop(wsize);
- register unsigned long t = upop(arg_wi(l));
- LOG(("@U6 DoRMUz(%ld)", l));
- spoilFRA();
- npush((long) rmu(upop(l), t), l);
- }
- DoSLUl2(arg)
- size arg;
- {
- /* SLU w: Shift left */
- register size l = (L_arg_2() * arg);
- register unsigned long t = upop(wsize);
- LOG(("@U6 DoSLUl2(%ld)", l));
- spoilFRA();
- l = arg_wi(l);
- npush((long) slu(upop(l), t, l), l);
- }
- DoSLUz()
- {
- /* SLU w: Shift left */
- register size l = upop(wsize);
- register unsigned long t = upop(wsize);
- LOG(("@U6 DoSLUz(%ld)", l));
- spoilFRA();
- l = arg_wi(l);
- npush((long) slu(upop(l), t, l), l);
- }
- DoSRUl2(arg)
- size arg;
- {
- /* SRU w: Shift right */
- register size l = (L_arg_2() * arg);
- register unsigned long t = upop(wsize);
- LOG(("@U6 DoSRUl2(%ld)", l));
- spoilFRA();
- l = arg_wi(l);
- npush((long) sru(upop(l), t, l), l);
- }
- DoSRUz()
- {
- /* SRU w: Shift right */
- register size l = upop(wsize);
- register unsigned long t = upop(wsize);
- LOG(("@U6 DoSRUz(%ld)", l));
- spoilFRA();
- l = arg_wi(l);
- npush((long) sru(upop(l), t, l), l);
- }
- PRIVATE unsigned long dvu(w1, w2)
- unsigned long w1, w2;
- {
- if (w2 == 0) {
- if (!(IgnMask&BIT(EIDIVZ))) {
- trap(EIDIVZ);
- }
- else return (0L);
- }
- return (w1 / w2);
- }
- PRIVATE unsigned long rmu(w1, w2)
- unsigned long w1, w2;
- {
- if (w2 == 0) {
- if (!(IgnMask&BIT(EIDIVZ))) {
- trap(EIDIVZ);
- }
- else return (0L);
- }
- return (w1 % w2);
- }
- /*ARGSUSED*/
- PRIVATE unsigned long slu(w1, w2, nbytes) /* w1 << w2 */
- unsigned long w1, w2;
- size nbytes;
- {
- #ifdef LOGGING
- if (must_test) {
- /* check shift distance */
- if (w2 >= nbytes*8) {
- warning(WSHLARGE);
- w2 = nbytes*8 - 1;
- }
- }
- #endif LOGGING
- /* calculate result */
- return (w1 << w2);
- }
- /*ARGSUSED*/
- PRIVATE unsigned long sru(w1, w2, nbytes) /* w1 >> w2 */
- unsigned long w1, w2;
- size nbytes;
- {
- #ifdef LOGGING
- if (must_test) {
- /* check shift distance */
- if (w2 >= nbytes*8) {
- warning(WSHLARGE);
- w2 = nbytes*8 - 1;
- }
- }
- #endif LOGGING
- /* calculate result */
- return (w1 >> w2);
- }
|