home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / lisp / liszt / fixnum.l < prev    next >
Encoding:
Text File  |  1988-04-26  |  17.6 KB  |  544 lines

  1. (include-if (null (get 'chead 'version)) "../chead.l")
  2. (Liszt-file fixnum
  3.    "$Header: /usr/src/local/franz/liszt/RCS/fixnum.l,v 1.16 88/04/26 11:50:18 sklower Exp $")
  4.  
  5. ;;; ----    f i x n u m        fixnum compilation
  6. ;;;
  7. ;;;                -[Fri Aug 26 14:07:53 1983 by layer]-
  8.  
  9. ;  There are a few functions in lisp which are only permitted to take
  10. ; fixnum operands and produce fixnum results.  The compiler recognizes
  11. ; these functions and open codes them.
  12. ;
  13.  
  14. ;--- d-fixnumexp :: compute a fixnum from an expression
  15. ;    x - a lisp expression which must return a fixnum
  16. ;
  17. ; This is an almost equivalent to d-exp, except that
  18. ; 1] it will do clever things if the expression can be open coded in a 
  19. ;    fixnum way.
  20. ; 2] the result must be a fixnum, and is left in r5 unboxed.
  21. ;
  22. (defun d-fixnumexp (x)
  23.   (d-fixnumcode (d-fixexpand x)))
  24.  
  25.  
  26. ;--- c-fixnumop :: compute a fixnum result
  27. ;  This is the extry point into this code from d-exp.  The form to evaluate
  28. ; is in v-form.  The only way we could get here is if the car of v-form
  29. ; is a function which we've stated is a fixnum returning function. 
  30. ;
  31. (defun c-fixnumop nil
  32.   (d-fixnumexp v-form)
  33.   (d-fixnumbox))
  34.  
  35. ;--- d-fixnumbox :: rebox a fixnum in r5
  36. ;
  37. #+(or for-vax for-tahoe)
  38. (defun d-fixnumbox ()
  39.    (let (x)
  40.     (e-write3 'moval (concat "*$5120[" '#.fixnum-reg "]") 'r0)
  41.     (e-sub3 '($ 1024) '#.fixnum-reg 'r1)
  42.     (e-write2 'blssu (setq x (d-genlab)))
  43.     (e-call-qnewint)
  44.     (e-writel x)
  45.     (d-clearreg)))
  46.  
  47. #+for-68k
  48. (defun d-fixnumbox ()
  49.    (let (x)
  50.     (d-regused '#.fixnum-reg)
  51.     (e-move '#.fixnum-reg 'd0)
  52.     (e-write3 'asll '($ 2) 'd0)
  53.     ; add onto the base of the fixnums
  54.     (e-add (e-cvt '(fixnum 0)) 'd0)
  55.     (e-move '#.fixnum-reg 'd1) 
  56.     (e-sub '($ 1024) 'd1)
  57.     (e-write2 'jcs (setq x (d-genlab)))    ;branch carry set
  58.     (e-call-qnewint)
  59.     (e-writel x)
  60.     (d-clearreg)))
  61.  
  62. ;--- d-fixexpand  :: pass over a fixnum expression doing local optimizations
  63. ; This code gets the first look at the operands of a fixnum expression.
  64. ; It handles the strange cases, like (+) or (/ 3), and it also insures
  65. ; that constants are folded (or collapsed as we call it here).
  66. ; things to watch out for:
  67. ; (+ x y z) we can fold x,y,z , likewise in the case of *
  68. ; (- x y z) we can only fold y and z since they are negated but x is not,
  69. ;        likewise for /
  70. (defun d-fixexpand (x)
  71.   (prog nil
  72.     (setq x (d-macroexpand x))
  73.     loop
  74.     (if (and (dtpr x) (symbolp (car x)) (get (car x) 'fixop))
  75.         then (if (memq (car x) '(+ *))
  76.              then  (setq x (cons (car x)
  77.                      (d-collapse (cdr x) (car x))))
  78.              else  (setq x
  79.                  (cons (car x)
  80.                        (cons (cadr x)
  81.                          (d-collapse (cddr x) (car x))))))
  82.              (if (null (cdr x))
  83.              then  ; (- or +) => 0 (* or /) => 1
  84.                  (setq x
  85.                    (cdr (assq (car x)
  86.                       '((+ . 0) (- . 0)
  87.                         (* . 1) (/ . 1)))))
  88.                  (go loop)
  89.           elseif (null (cddr x)) then
  90.                    ; (+ n) => n, (- n) => (- 0 n), (* n) => n,
  91.                ; (/ n) => (/ 1 n)
  92.               (setq x
  93.                 (if (memq (car x) '(* +))
  94.                     then (cadr x)
  95.                  elseif (eq (car x) '-)
  96.                     then `(- 0 ,(cadr x))
  97.                  elseif (eq (car x) '/)
  98.                     then `(/ 1 ,(cadr x))
  99.                     else (comp-err
  100.                          "Internal fixexpand error ")))
  101.               (go loop)))
  102.     (return x)))
  103.  
  104. ;--- d-toplevmacroexpand :: expand top level form if macro
  105. ; a singe level of macro expansion is done.  this is a nice general
  106. ; routine and should be used by d-exp.
  107. ;**** out of date **** will be removed soon
  108. (defun d-toplevmacroexpand (x)
  109.   (let ((fnbnd (and (dtpr x) (symbolp (car x)) (getd (car x)))))
  110.        (if (and fnbnd (or (and (bcdp fnbnd) (eq (getdisc fnbnd) 'macro))
  111.               (and (dtpr fnbnd) (eq (car fnbnd) 'macro))))
  112.        then (d-toplevmacroexpand (apply fnbnd x))
  113.        else x)))
  114.  
  115.  
  116. ;--- d-collapse :: collapse (fold) constants
  117. ; this is used to reduce the number of operations. since we know that
  118. ; fixnum operations are commutative.
  119. ;
  120. (defun d-collapse (form op)
  121.   (let (const res conlist)
  122.        ; generate list of constants (conlist) and non constants (res)
  123.        (do ((xx form (cdr xx)))
  124.        ((null xx))
  125.        (if (numberp (car xx))
  126.            then (if (fixp (car xx))
  127.             then (setq conlist (cons (car xx) conlist))
  128.             else (comp-err "Illegal operand in fixnum op " 
  129.                        (car xx)))
  130.            else (setq res (cons (car xx) res))))
  131.  
  132.        ; if no constants found thats ok, but if we found some,
  133.        ; then collapse and return the form with the collapsed constant
  134.        ; at the end.
  135.  
  136.        (if (null conlist)
  137.        then form     ; no change
  138.        else (setq res (nreverse 
  139.          (cons (apply (cond ((or (eq op '/) (eq op '*)) 'times)
  140.                     (t 'plus)) 
  141.                   (cons (cond ((or (eq op '/) (eq op '*)) 1)
  142.                       (t 0))
  143.                     conlist))
  144.                res))))))
  145.  
  146.  
  147. ;---- d-fixnumcode :: emit code for prescanned fixnum expression
  148. ;    expr -  a expression which should return an unboxed fixnum value 
  149. ;        in r5.
  150. ;  This function checks if the expression is indeed a guaranteed fixnum 
  151. ; arithmetic expression, and if so , generates code for the operation.
  152. ; If the expression is not a fixnum operation, then a normal evaluation
  153. ; of the cdr of the expression is done, which will grab the fixnum value
  154. ; and put it in r5.
  155. ;
  156. #+(or for-vax for-tahoe)
  157. (defun d-fixnumcode (expr)
  158.   (let ((operator (and (dtpr expr) 
  159.                (symbolp (car expr)) 
  160.                (get (car expr) 'fixop)))
  161.     (g-ret nil)
  162.     tmp)
  163.        ; the existance of a fixop property on a function says that it is a
  164.        ; special fixnum only operation.
  165.        (if (null operator) 
  166.        then (let ((g-loc '#.fixnum-reg) g-cc) ; non fixnum op, do normal
  167.              (d-exp `(cdr ,expr)))    ; eval to get unboxed number
  168.        else (do ((xx (cdr expr) (cdr xx))    ; fixnum op, scan all args
  169.              (lop) (rop) (res) (opnd))
  170.             ((null xx))
  171.             (setq opnd (car xx))
  172.             (if (fixp opnd) 
  173.             then (setq rop `(immed ,opnd))
  174.                 elseif (and (symbolp opnd) 
  175.                  (setq rop (d-simple `(cdr ,opnd))))
  176.                 thenret
  177.             else (if (and lop (not (eq lop '#.unCstack)))
  178.                  then (C-push (e-cvt lop))
  179.                  (setq lop '#.unCstack))
  180.                  (d-fixnumcode (d-fixexpand opnd))
  181.                  (setq rop 'r5))
  182.             (if (null lop) 
  183.             then (if (cdr xx) 
  184.                  then (setq lop rop)
  185.                  else (e-move (e-cvt rop) 'r5))
  186.             else (if (cdr xx) 
  187.                  then (setq res '#.Cstack)
  188.                  else (setq res 'r5))
  189.                  (if (setq tmp (d-shiftcheck operator rop))
  190.                  then (e-write4 #+for-vax 'ashl 
  191.                         #+for-tahoe 'shal
  192.                         (e-cvt (list 'immed tmp))
  193.                         (e-cvt lop)
  194.                         (e-cvt res))
  195.                  else (e-write4 operator (e-cvt rop) 
  196.                         (e-cvt lop) 
  197.                         (e-cvt res)))
  198.                  (if (cdr xx) 
  199.                  then (setq lop '#.unCstack)
  200.                  else (setq lop "r5")))))))
  201.  
  202. #+for-68k
  203. (defun d-fixnumcode (expr)
  204.    (let ((operator (and (dtpr expr)
  205.             (symbolp (car expr))
  206.             (get (car expr) 'fixop)))
  207.      (g-ret nil)
  208.      tmp)
  209.        ; the existance of a fixop property on a function says that it is a
  210.        ; special fixnum only operation.
  211.        (makecomment `(d-fixnumcode ,expr))
  212.        (if (null operator) 
  213.        then (let ((g-loc '#.fixnum-reg) g-cc) ; non fixnum op, do normal
  214.             (d-exp `(cdr ,expr)))      ; eval to get unboxed number
  215.         (d-regused '#.fixnum-reg)
  216.        else (do ((xx (cdr expr) (cdr xx))      ; fixnum op, scan all args
  217.              (lop) (rop) (res) (opnd))
  218.             ((null xx))
  219.             (setq opnd (car xx))
  220.             (if (fixp opnd) 
  221.             then (setq rop `(immed ,opnd))
  222.              elseif (and (symbolp opnd)
  223.                  (setq rop (d-simple `(cdr ,opnd))))
  224.             thenret
  225.             else (if (and lop (not (eq lop '#.unCstack)))
  226.                  then (C-push (e-cvt lop))
  227.                       (setq lop '#.unCstack))
  228.                  (d-fixnumcode (d-fixexpand opnd))
  229.                  (setq rop '#.fixnum-reg))
  230.             (if (null lop) 
  231.             then (if (cdr xx) 
  232.                  then (setq lop rop)
  233.                  else (e-move
  234.                         (e-cvt rop)
  235.                         '#.fixnum-reg))
  236.             else (if (cdr xx) 
  237.                  then (setq res '#.Cstack)
  238.                  else (setq res '#.fixnum-reg))
  239.                  (if (setq tmp (d-shiftcheck operator rop))
  240.                  then (d-asll tmp (e-cvt lop) (e-cvt res))
  241.                  else (e-move (e-cvt lop) 'd0)
  242.                       (e-write3 operator (e-cvt rop) 'd0)
  243.                       (e-move 'd0 (e-cvt res)))
  244.                  (if (cdr xx) 
  245.                  then (setq lop '#.unCstack)
  246.                  else (setq lop '#.fixnum-reg)))))
  247.        (makecomment '(d-fixnumcode done))))
  248.  
  249. ;--- d-shiftcheck    :: check if we can shift instead of multiply
  250. ; return t if the operator is a multiply and the operand is an
  251. ; immediate whose value is a power of two.
  252. (defun d-shiftcheck (operator operand)
  253.    (and (eq operator #+(or for-vax for-tahoe) 'lmul
  254.                  #+for-68k 'mull3)
  255.     (dtpr operand)
  256.     (eq (car operand) 'immed)
  257.     (cdr (assoc (cadr operand) arithequiv))))
  258.  
  259. ; this table is incomplete 
  260. ;
  261. (setq arithequiv '((1 . 0) (2 . 1) (4 . 2) (8 . 3) (16 . 4) (32 . 5)
  262.            (64 . 6) (128 . 7) (256 . 8) (512 . 9) (1024 . 10)
  263.            (2048 . 11) (4096 . 12) (8192 . 13) (16384 . 14)
  264.            (32768 . 15) (65536 . 16) (131072 . 17)))
  265.  
  266.  
  267. ;--- cc-oneplus  :: compile 1+ form            = cc-oneplus =
  268. ;  1+ increments a fixnum only. We generate code to check if the number
  269. ; to be incremented is a small fixnum less than or equal to 1022.  This
  270. ; check is done by checking the address of the fixnum's box.  If the
  271. ; number is in that range, we just increment the box pointer by 4.
  272. ; otherwise we call we call _qoneplus which does the add and calls
  273. ; _qnewint
  274. ;
  275. #+(or for-vax for-tahoe)
  276. (defun cc-oneplus nil
  277.   (if (null g-loc)
  278.       then (if (car g-cc) then (e-goto (car g-cc)))
  279.       else (let ((argloc (d-simple (cadr v-form)))
  280.          (lab1 (d-genlab))
  281.          (lab2 (d-genlab)))
  282.         (if (null argloc) 
  283.             then (let ((g-loc 'r0) g-cc g-ret)
  284.                   (d-exp (cadr v-form)))
  285.              (setq argloc 'reg))
  286.         (e-cmp (e-cvt argloc) '($ #.(+ 5120 (* 4 1022))))
  287.         (e-write2 'jleq lab1)
  288.         (if (not (eq argloc 'r0)) then (d-move argloc 'reg))
  289.         (e-quick-call '_qoneplus)
  290.         (if (and g-loc (not (eq g-loc 'reg)))
  291.             then (d-move 'reg g-loc))
  292.         (if (car g-cc)
  293.             then (e-goto (car g-cc))
  294.             else (e-goto lab2))
  295.         (e-label lab1)
  296.         (e-add3 '($ 4) (e-cvt argloc) (e-cvt g-loc))
  297.         (if (car g-cc) then (e-goto (car g-cc)))
  298.         (e-label lab2))))
  299.  
  300. #+for-68k
  301. (defun cc-oneplus nil
  302.    (if (null g-loc)
  303.        then (if (car g-cc) then (e-goto (car g-cc)))
  304.        else (let ((argloc (d-simple (cadr v-form)))
  305.           (lab1 (d-genlab))
  306.           (lab2 (d-genlab)))
  307.         (if (null argloc) 
  308.             then (let ((g-loc 'areg) g-cc g-ret)
  309.                  (d-exp (cadr v-form)))
  310.              (setq argloc 'areg))
  311.         ; ($ (+ Fixzero (* 4 1022))
  312.         (d-cmp argloc '(fixnum 1022))
  313.         (e-write2 'jle lab1)
  314.         (if (not (eq argloc 'areg)) then (d-move argloc 'areg))
  315.         (e-quick-call '_qoneplus)
  316.         (if (and g-loc (not (eq g-loc 'reg)))
  317.             then (d-move 'reg g-loc))
  318.         (if (car g-cc)
  319.             then (e-goto (car g-cc))
  320.             else (e-goto lab2))
  321.         (e-label lab1)
  322.         (if (not (eq argloc 'reg))
  323.             then (d-move argloc 'reg))
  324.         (e-write3 'addql "#4" 'd0)
  325.         (if (and g-loc (not (eq g-loc 'reg)))
  326.             then (d-move 'reg g-loc))
  327.         (if (car g-cc) then (e-goto (car g-cc)))
  328.         (e-label lab2))))
  329.             
  330.  
  331.  
  332. ;--- cc-oneminus :: compile the 1- form
  333. ; just like 1+ we check to see if we are decrementing an small fixnum.
  334. ; and if we are we just decrement the pointer to the fixnum and save
  335. ; a call to qinewint.  The valid range of fixnums we can decrement are
  336. ; 1023 to -1023.  This requires two range checks (as opposed to one for 1+).
  337. ;
  338. #+(or for-vax for-tahoe)
  339. (defun cc-oneminus nil
  340.   (if (null g-loc)
  341.       then (if (car g-cc) then (e-goto (car g-cc)))
  342.       else (let ((argloc (d-simple (cadr v-form)))
  343.          (lab1 (d-genlab))
  344.          (lab2 (d-genlab))
  345.          (lab3 (d-genlab)))
  346.         (if (null argloc) 
  347.             then (let ((g-loc 'r0) g-cc)
  348.                   (d-exp (cadr v-form)))
  349.                  (setq argloc 'reg))
  350.         (e-cmp (e-cvt argloc) '($ #.(- 5120 (* 4 1024))))
  351.         (e-write2 'jleq lab1)    ; not within range
  352.         (e-cmp (e-cvt argloc) '($ #.(+ 5120 (* 4 1023))))
  353.         (e-write2 'jleq lab2)    ; within range
  354.         ; not within range, must do it the hard way.
  355.         (e-label lab1)
  356.         (if (not (eq argloc 'r0)) then (d-move argloc 'reg))
  357.         (e-quick-call '_qoneminus)
  358.         (if (and g-loc (not (eq g-loc 'reg)))
  359.             then (d-move 'reg g-loc))
  360.         (if (car g-cc)
  361.             then (e-goto (car g-cc))
  362.             else (e-goto lab3))
  363.         (e-label lab2)
  364.         ; we are within range, just decrement the pointer by the
  365.         ; size of a word (4 bytes).
  366.         (e-sub3 '($ 4) (e-cvt argloc) (e-cvt g-loc))
  367.         (if (car g-cc) then (e-goto (car g-cc)))
  368.         (e-label lab3))))
  369.  
  370. #+for-68k
  371. (defun cc-oneminus nil
  372.   (if (null g-loc)
  373.       then (if (car g-cc) then (e-goto (car g-cc)))
  374.       else (let ((argloc (d-simple (cadr v-form)))
  375.          (lab1 (d-genlab))
  376.          (lab2 (d-genlab))
  377.          (lab3 (d-genlab)))
  378.         (if (null argloc) 
  379.             then (let ((g-loc 'areg) g-cc)
  380.                   (d-exp (cadr v-form)))
  381.                  (setq argloc 'areg))
  382.         ; ($ (- Fixzero (* 4 1024)))
  383.         (d-cmp argloc '(fixnum -1024))
  384.         (e-write2 'jle lab1)    ; not within range
  385.         (d-cmp argloc '(fixnum 1023))
  386.         (e-write2 'jle lab2)    ; within range
  387.         ; not within range, must do it the hard way.
  388.         (e-label lab1)
  389.         (if (not (eq argloc 'areg)) then (d-move argloc 'areg))
  390.         (e-quick-call '_qoneminus)
  391.         (if (and g-loc (not (eq g-loc 'reg)))
  392.             then (d-move 'reg g-loc))
  393.         (if (car g-cc)
  394.             then (e-goto (car g-cc))
  395.             else (e-goto lab3))
  396.         (e-label lab2)
  397.         ; we are within range, just decrement the pointer by the
  398.         ; size of a word (4 bytes).
  399.         (if (not (eq argloc 'reg))
  400.             then (d-move argloc 'reg))
  401.         (e-sub '($ 4) 'd0)
  402.         (if (and g-loc (not (eq g-loc 'reg)))
  403.             then (d-move 'reg g-loc))
  404.         (if (car g-cc) then (e-goto (car g-cc)))
  405.         (e-label lab3))))
  406.  
  407. ;--- cm-<  :: compile a < expression
  408. ; the operands to this form can either be fixnum or flonums but they
  409. ; must be of the same type.
  410. ;
  411. ; We can compile the form just like an eq form since all we want is
  412. ; a compare and a jump.  The comparisons are inverted since that is
  413. ; the way eq expects it.
  414.  
  415. (defun cm-< nil
  416.    (if (not (= 2 (length (cdr v-form))))
  417.       then (comp-err "incorrect number of arguments to < " v-form))
  418.    ; only can do fixnum stuff if we know that one of the args is
  419.    ; a fixnum.
  420.    ;
  421.    (if (or (fixp (cadr v-form)) (fixp (caddr v-form)))
  422.       then `(<& ,(cadr v-form) ,(caddr v-form))
  423.       else `(lessp ,(cadr v-form) ,(caddr v-form))))
  424.  
  425. ;--- c-<& :: fixnum <
  426. ;
  427. ; We can compile the form just like an eq form since all we want is
  428. ; a compare and a jump.  The comparisons are inverted since that is
  429. ; the way eq expects it.
  430.  
  431. (defun cc-<& nil
  432.    (let ((g-trueop  #+(or for-vax for-tahoe) 'jgeq #+for-68k 'jpl)
  433.      (g-falseop #+(or for-vax for-tahoe) 'jlss #+for-68k 'jmi)
  434.      (v-form `(eq (cdr ,(cadr v-form)) (cdr ,(caddr v-form)))))
  435.       (cc-eq)))
  436.  
  437. ;--- cm->  :: compile a > expression
  438. ;
  439. ; the operands to this form can either be fixnum or flonums but they
  440. ; must be of the same type.  
  441. ; We can compile the form just like an eq form since all we want is
  442. ; a compare and a jump.  The comparisons are inverted since that is
  443. ; the way eq expects it.
  444. (defun cm-> nil
  445.    (if (not (= 2 (length (cdr v-form))))
  446.       then (comp-err "incorrect number of arguments to > " v-form))
  447.    ; only can do fixnum stuff if we know that one of the args is
  448.    ; a fixnum.
  449.    ;
  450.    (if (or (fixp (cadr v-form)) (fixp (caddr v-form)))
  451.       then `(>& ,(cadr v-form) ,(caddr v-form))
  452.       else `(greaterp ,(cadr v-form) ,(caddr v-form))))
  453.  
  454. ;--- cc->& :: compile a fixnum > function
  455. ;
  456. ; We can compile the form just like an eq form since all we want is
  457. ; a compare and a jump.  The comparisons are inverted since that is
  458. ; the way eq expects it.
  459. (defun cc->& nil
  460.    (let ((g-trueop  #+(or for-vax for-tahoe) 'jleq #+for-68k 'jle)
  461.      (g-falseop #+(or for-vax for-tahoe) 'jgtr #+for-68k 'jgt)
  462.      (v-form `(eq (cdr ,(cadr v-form)) (cdr ,(caddr v-form)))))
  463.       (cc-eq)))
  464.  
  465. ;--- cm-=  : compile an = expression
  466. ;  The = function is a strange one.  It can compare two fixnums or two
  467. ; flonums which is fine on a pdp-10 where they are the same size, but
  468. ; is a real pain on a vax where they are different sizes.
  469. ; We thus can see if one of the arguments is a fixnum and assume that
  470. ; the other one is and then  call =&, the fixnum equal code.
  471. ;
  472. (defun cm-= nil
  473.    (if (not (= 2 (length (cdr v-form))))
  474.       then (comp-err "incorrect number of arguments to = : " v-form))
  475.    (if (or (fixp (cadr v-form)) (fixp (caddr v-form)))
  476.       then `(=& ,(cadr v-form) ,(caddr v-form))
  477.       else `(equal ,(cadr v-form) ,(caddr v-form))))
  478.  
  479. ;--- cm-=&
  480. ;
  481. ; if the number is within the small fixnum range, we can just
  482. ; do pointer comparisons.
  483. ;
  484. (defun cm-=& nil
  485.    (if (or (and (fixp (cadr v-form))
  486.         (< (cadr v-form) 1024)
  487.         (> (cadr v-form) -1025))
  488.        (and (fixp (caddr v-form))
  489.         (< (caddr v-form) 1024)
  490.         (> (caddr v-form) -1025)))
  491.       then `(eq ,(cadr v-form) ,(caddr v-form))
  492.       else `(eq (cdr ,(cadr v-form)) (cdr ,(caddr v-form)))))
  493.  
  494. ; this should be converted
  495. #+(or for-vax for-tahoe)
  496. (defun c-\\ nil
  497.    (d-fixop 'ediv  'remainder))
  498.  
  499. #+(or for-vax for-tahoe)
  500. (defun d-fixop (opcode lispopcode)
  501.    (prog (op1 op2 rop1 rop2 simpleop1)
  502.        (if (not (eq 3 (length v-form))) ; only handle two ops for now
  503.        then (d-callbig lispopcode (cdr v-form) nil)
  504.        else (setq op1 (cadr v-form)
  505.               op2 (caddr v-form))
  506.         (if (fixp op1)
  507.             then (setq rop1 `($ ,op1)  ; simple int
  508.                    simpleop1 t)        
  509.             else (if (setq rop1 (d-simple `(cdr ,op1)))
  510.                  then (setq rop1 (e-cvt rop1))
  511.                  else (let ((g-loc 'reg) g-cc g-ret)
  512.                       (d-exp op1))
  513.                   (setq rop1 '(0 r0))))
  514.         (if (fixp op2)
  515.             then (setq rop2 `($ ,op2))
  516.             else (if (setq rop2 (d-simple `(cdr ,op2)))
  517.                  then (setq rop2 (e-cvt rop2))
  518.                  else (C-push rop1)
  519.                   (setq rop1 '#.unCstack)
  520.                   (let ((g-loc 'reg)
  521.                     g-cc g-ret)
  522.                       (d-exp op2))
  523.                   (setq rop2 '(0 r0))))
  524.         (if (eq opcode 'ediv)
  525.             then (if (not simpleop1)
  526.                  then #+for-vax (progn (e-move rop1 'r2) ;need quad
  527.                         (e-write4 'ashq '$-32 'r1 'r1))
  528.                       #+for-tahoe (let ((x (d-genlab)))
  529.                         (e-write2 'clrl 'r2)
  530.                         (e-move rop1 'r3)
  531.                         (e-write2 'jgeq x)
  532.                         (e-write3 'mnegl '($ 1) 'r2)
  533.                         (e-writel x))
  534.                   (setq rop1 #+for-vax 'r1 #+for-tahoe 'r2))
  535.                                   ; word div.
  536.              (e-write5 'ediv rop2 rop1 'r0 'r5)
  537.             else (e-write4 opcode rop2 rop1 'r5))
  538.         (d-fixnumbox)
  539.         (d-clearreg))))
  540.