~ubuntu-branches/ubuntu/trusty/mit-scheme/trusty

« back to all changes in this revision

Viewing changes to src/compiler/machines/i386/rulfix.scm

  • Committer: Bazaar Package Importer
  • Author(s): Chris Hanson
  • Date: 2010-03-10 02:00:45 UTC
  • mfrom: (1.1.7 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100310020045-4np1y3ro6sk2oz92
Tags: 9.0.1-1
* New upstream.
* debian/watch: Fix, previous version was broken.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#| -*-Scheme-*-
2
2
 
3
 
$Id: rulfix.scm,v 1.39 2008/01/30 20:01:50 cph Exp $
4
 
 
5
3
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
6
4
    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
7
 
    2006, 2007, 2008 Massachusetts Institute of Technology
 
5
    2006, 2007, 2008, 2009, 2010 Massachusetts Institute of Technology
8
6
 
9
7
This file is part of MIT/GNU Scheme.
10
8
 
482
480
                   (SAR W ,target (& ,scheme-type-width))
483
481
                   (IMUL W ,target ,temp))))))))
484
482
 
 
483
;;; This calls an out-of-line assembly hook because it requires a lot
 
484
;;; of hair to deal with shift counts that exceed the datum width, and
 
485
;;; with negative arguments.
 
486
 
485
487
(define-arithmetic-method 'FIXNUM-LSH fixnum-methods/2-args
486
 
  (let ((operate
487
 
         (lambda (target source2)
488
 
           ;; SOURCE2 is guaranteed not to be ECX because of the
489
 
           ;; require-register! used below.
490
 
           ;; TARGET can be ECX only if the rule has machine register
491
 
           ;; ECX as the target, unlikely, but it must be handled!
492
 
           (let ((with-target
493
 
                   (lambda (target)
494
 
                     (let ((jlabel (generate-label 'SHIFT-JOIN))
495
 
                           (slabel (generate-label 'SHIFT-NEGATIVE)))
496
 
                       (LAP (MOV W (R ,ecx) ,source2)
497
 
                            (SAR W (R ,ecx) (& ,scheme-type-width))
498
 
                            (JS B (@PCR ,slabel))
499
 
                            (SHL W ,target (R ,ecx))
500
 
                            (JMP B (@PCR ,jlabel))
501
 
                            (LABEL ,slabel)
502
 
                            (NEG W (R ,ecx))
503
 
                            (SHR W ,target (R ,ecx))
504
 
                            ,@(word->fixnum target)
505
 
                            (LABEL ,jlabel))))))
506
 
 
507
 
             (if (not (equal? target (INST-EA (R ,ecx))))
508
 
                 (with-target target)
509
 
                 (let ((temp (temporary-register-reference)))
510
 
                   (LAP (MOV W ,temp ,target)
511
 
                        ,@(with-target temp)
512
 
                        (MOV W ,target ,temp))))))))
513
 
    (lambda (target source1 source2 overflow?)
514
 
      overflow?                         ; ignored
515
 
      (require-register! ecx)
516
 
      (two-arg-register-operation operate
517
 
                                  #f
518
 
                                  target
519
 
                                  source1
520
 
                                  source2))))
 
488
  (lambda (target source1 source2 overflow?)
 
489
    overflow?                           ;ignore
 
490
    ;++ This is suboptimal in the cases when SOURCE1 is stored only in
 
491
    ;++ ecx or when SOURCE2 is stored only in eax, and either one is
 
492
    ;++ dead (which is often the case).  In such cases, this generates
 
493
    ;++ code to needlessly save the dead pseudo-registers into their
 
494
    ;++ homes simply because they were stored in eax and ecx.  It'd be
 
495
    ;++ nice to have a variant of LOAD-MACHINE-REGISTER! for multiple
 
496
    ;++ sources and targets, which would compute a parallel assignment
 
497
    ;++ using machine registers if available for temporaries, or the
 
498
    ;++ homes of pseudo-registers if not.
 
499
    (let* ((load-eax (load-machine-register! source1 eax))
 
500
           (load-ecx (load-machine-register! source2 ecx)))
 
501
      (delete-dead-registers!)
 
502
      (rtl-target:=machine-register! target eax)
 
503
      (LAP ,@load-eax
 
504
           ,@load-ecx
 
505
           ;; Clearing the map is not necessary because the hook uses
 
506
           ;; only eax and ecx.  If the hook were changed, it would be
 
507
           ;; necessary to clear the map first.
 
508
           ,@(invoke-hook/call entry:compiler-fixnum-shift)))))
521
509
 
522
510
(define (do-division target source1 source2 result-reg)
523
511
  (prefix-instructions! (load-machine-register! source1 eax))