Changeset 6313


Ignore:
Timestamp:
Apr 20, 2007, 8:55:52 AM (15 years ago)
Author:
gb
Message:

Support for :talign pseudo-op: aligns the -end- of the next instruction
on a specified boundary. (This is intended to allow use of CALL instructions
in some cases, forcing the return address to be tagged properly.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/x8664-call/ccl/compiler/X86/x86-lap.lisp

    r6295 r6313  
    344344    (new-frag frag-list)))
    345345
     346;;; Make the current frag be of type :talign; set that frag-type's
     347;;; argument to NIL initially.  Start a new frag of type :pending-talign;
     348;;; that frag will contain at most one instruction.  When an
     349;;; instuction is ouput in the pending-talign frag, adjust the preceding
     350;;; :talign frag's argument and set the type of the :pending-talign
     351;;; frag to NIL.  (The :talign frag will have 0-7 NOPs of some form
     352;;; appended to it, so the first instruction in the successor will end
     353;;; on an address that matches the argument below.)
     354;;; That instruction can not be a relaxable branch.
     355(defun finish-frag-for-talign (frag-list arg)
     356  (let* ((current (frag-list-current frag-list))
     357         (new (new-frag frag-list)))
     358    (setf (frag-type current) (list :talign nil))
     359    (setf (frag-type new) (list :pending-talign arg))))
     360
     361;;; Having generated an instruction in a :pending-talign frag, set the
     362;;; frag-type argument of the preceding :talign frag to the :pendint-talign
     363;;; frag's argument - the length of the pending-talign's first instruction
     364;;; mod 8, and clear the type of the "pending" frag.
     365;;; cadr of the frag-type
     366(defun finish-pending-talign-frag (frag-list)
     367  (let* ((frag (frag-list-current frag-list))
     368         (pred (frag-pred frag))
     369         (arg (cadr (frag-type frag)))
     370         (pred-arg (frag-type pred)))
     371    (setf (cadr pred-arg) (logand 7 (- arg (frag-length frag)))
     372          (frag-type frag) nil)
     373    (new-frag frag-list)))
     374
    346375(defun finish-frag-for-org (frag-list org)
    347376  (let* ((frag (frag-list-current frag-list)))
    348377    (setf (frag-type frag) (list :org org))
    349378    (new-frag frag-list)))
     379
    350380
    351381(defun lookup-x86-register (regname designator)
     
    968998                   (if (logtest optype (x86::encode-operand-type :imm64))
    969999                     (frag-list-push-64 frag-list val)
    970                      (frag-list-push-32 frag-list val))))))))))))
     1000                     (frag-list-push-32 frag-list val))))))))))
     1001    (let* ((frag (frag-list-current frag-list)))
     1002      (if (eq (car (frag-type frag)) :pending-talign)
     1003        (finish-pending-talign-frag frag-list)))))
    9711004
    9721005(defun x86-lap-directive (frag-list directive arg)
     
    9971030                (:quad (frag-list-push-64 frag-list val))
    9981031                (:align (finish-frag-for-align frag-list val))
     1032                (:talign (finish-frag-for-talign frag-list val))
    9991033                (:org (finish-frag-for-org frag-list val))))
    10001034            (let* ((pos (frag-list-position frag-list))
     
    10101044                (:quad (frag-list-push-64 frag-list 0)
    10111045                       (setq reloctype :expr64))
    1012                 (:align (error ":align expression ~s not constant" arg)))
     1046                (:align (error ":align expression ~s not constant" arg))
     1047                (:talign (error ":talign expression ~s not constant" arg)))
    10131048              (when reloctype
    10141049                (push
     
    10621097    (- (logandc2 (+ address mask) mask) address)))
    10631098
     1099(defun relax-talign (address mask)
     1100  (do* ((i 0 (1+ i)))
     1101       ((= (logand address 7) mask) i)
     1102    (incf address)))
     1103
     1104
    10641105(defun relax-frag-list (frag-list)
    10651106  ;; First, assign tentative addresses to all frags, assuming that
     
    10821123                (:align
    10831124                 (incf address (relax-align address (cadr (frag-type frag)))))
     1125                (:talign
     1126                 (let* ((arg (cadr (frag-type frag))))
     1127                   (if (null arg)
     1128                     ;;; Never generated code in :pending-talign frag
     1129                     (setf (frag-type frag) nil)
     1130                     (incf address (relax-talign address arg)))))
    10841131                ((:assumed-short-branch :assumed-short-conditional-branch)
    10851132                 (destructuring-bind (label pos reloc) (cdr (frag-type frag))
     
    11321179                    (oldoff (relax-align (+ was-address len) bits))
    11331180                    (newoff (relax-align (+ address len) bits)))
     1181               (setq growth (- newoff oldoff))))
     1182            (:talign
     1183             (let* ((arg (cadr fragtype))
     1184                    (len (frag-length frag))
     1185                    (oldoff (relax-talign (+ was-address len) arg))
     1186                    (newoff (relax-talign (+ address len) arg)))
    11341187               (setq growth (- newoff oldoff))))
    11351188            ;; If we discover - on any iteration - that a short
     
    12071260                             
    12081261
     1262(defun frag-emit-nops (frag count)
     1263  (let* ((nnops (ash (+ count 3) -2))
     1264         (len (floor count nnops))
     1265         (remains (- count (* nnops len))))
     1266    (dotimes (i remains)
     1267      (dotimes (k len) (frag-push-byte frag #x66))
     1268      (frag-push-byte frag #x90))
     1269    (do* ((i remains (1+ i)))
     1270         ((= i nnops))
     1271      (dotimes (k (1- len)) (frag-push-byte frag #x66))
     1272      (frag-push-byte frag #x90))))
     1273 
    12091274(defun fill-for-alignment (frag-list)
    12101275  (ccl::do-dll-nodes (frag frag-list)
     
    12151280               (pad (- nextaddr (+ addr (frag-length frag)))))
    12161281          (unless (eql 0 pad)
    1217             (dotimes (i pad) (frag-push-byte frag #xcc))))))))
     1282            (if (eq (car (frag-type frag)) :talign)
     1283              (frag-emit-nops frag pad)
     1284              (dotimes (i pad) (frag-push-byte frag #xcc)))))))))
    12181285
    12191286(defun show-frag-bytes (frag-list)
Note: See TracChangeset for help on using the changeset viewer.