Changeset 6313
- Timestamp:
- Apr 20, 2007, 1:55:52 AM (18 years ago)
- File:
-
- 1 edited
-
branches/x8664-call/ccl/compiler/X86/x86-lap.lisp (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/x8664-call/ccl/compiler/X86/x86-lap.lisp
r6295 r6313 344 344 (new-frag frag-list))) 345 345 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 346 375 (defun finish-frag-for-org (frag-list org) 347 376 (let* ((frag (frag-list-current frag-list))) 348 377 (setf (frag-type frag) (list :org org)) 349 378 (new-frag frag-list))) 379 350 380 351 381 (defun lookup-x86-register (regname designator) … … 968 998 (if (logtest optype (x86::encode-operand-type :imm64)) 969 999 (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))))) 971 1004 972 1005 (defun x86-lap-directive (frag-list directive arg) … … 997 1030 (:quad (frag-list-push-64 frag-list val)) 998 1031 (:align (finish-frag-for-align frag-list val)) 1032 (:talign (finish-frag-for-talign frag-list val)) 999 1033 (:org (finish-frag-for-org frag-list val)))) 1000 1034 (let* ((pos (frag-list-position frag-list)) … … 1010 1044 (:quad (frag-list-push-64 frag-list 0) 1011 1045 (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))) 1013 1048 (when reloctype 1014 1049 (push … … 1062 1097 (- (logandc2 (+ address mask) mask) address))) 1063 1098 1099 (defun relax-talign (address mask) 1100 (do* ((i 0 (1+ i))) 1101 ((= (logand address 7) mask) i) 1102 (incf address))) 1103 1104 1064 1105 (defun relax-frag-list (frag-list) 1065 1106 ;; First, assign tentative addresses to all frags, assuming that … … 1082 1123 (:align 1083 1124 (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))))) 1084 1131 ((:assumed-short-branch :assumed-short-conditional-branch) 1085 1132 (destructuring-bind (label pos reloc) (cdr (frag-type frag)) … … 1132 1179 (oldoff (relax-align (+ was-address len) bits)) 1133 1180 (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))) 1134 1187 (setq growth (- newoff oldoff)))) 1135 1188 ;; If we discover - on any iteration - that a short … … 1207 1260 1208 1261 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 1209 1274 (defun fill-for-alignment (frag-list) 1210 1275 (ccl::do-dll-nodes (frag frag-list) … … 1215 1280 (pad (- nextaddr (+ addr (frag-length frag))))) 1216 1281 (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))))))))) 1218 1285 1219 1286 (defun show-frag-bytes (frag-list)
Note:
See TracChangeset
for help on using the changeset viewer.
