Changeset 16630


Ignore:
Timestamp:
Oct 31, 2015, 2:05:27 AM (6 years ago)
Author:
rme
Message:

Use Intel-recommended multi-byte NOP instructions in frag-emit-nops.
Try to teach the disassembler how to print a multi-byte NOP.

In check_x86_cpu(), require the processor to support multi-byte NOP.
Almost any processor that supports conditional moves will support
multi-byte NOP, so this should theoretically not be a burdensome
requirement.

Location:
trunk/source
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/compiler/X86/x86-disassemble.lisp

    r16573 r16630  
    12301230   (make-x86-dis "(bad)")
    12311231   (make-x86-dis "(bad)")
    1232    (make-x86-dis "(bad)")
     1232   (make-x86-dis "nopS" 'op-e +v-mode+)
    12331233   ;; #x20
    12341234   (make-x86-dis "movL" 'op-rd +m-mode+ 'op-c +m-mode+)
     
    15171517  #|       -------------------------------        |#
    15181518  #| 00 |# 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1  #| 0f |#
    1519   #| 10 |# 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0  #| 1f |#
     1519  #| 10 |# 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1  #| 1f |#
    15201520  #| 20 |# 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1  #| 2f |#
    15211521  #| 30 |# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  #| 3f |#
  • trunk/source/compiler/X86/x86-lap.lisp

    r16574 r16630  
    13561356                    (:self (emit-long frag pos (x86-lap-expression-value arg)))))))))))))
    13571357
    1358 (defstatic *x86-32-bit-lap-nops*
    1359   #(
    1360     #()
    1361     #(#x90)                             ; nop                 
    1362     #(#x89 #xf6)                        ; movl %esi,%esi       
    1363     #(#x8d #x76 #x00)                   ; leal 0(%esi),%esi   
    1364     #(#x8d #x74 #x26 #x00)              ; leal 0(%esi,1),%esi 
    1365     #(#x90 #x8d #x74 #x26 #x00)         ; nop ; leal 0(%esi,1),%esi 
    1366     #(#x8d #xb6 #x00 #x00 #x00 #x00)    ; leal 0L(%esi),%esi   
    1367     #(#x8d #xb4 #x26 #x00 #x00 #x00 #x00) ; leal 0L(%esi,1),%esi
    1368   )
    1369   "Allegedly, many implementations recognize these instructions and
    1370 execute them very quickly.")
    1371 
    1372 (defstatic *x86-32-bit-lap-nops-8*
    1373   #(#x90 #x8d #xb4 #x26 #x00 #x00 #x00 #x00))
     1358;;; Recommended multi-byte nop instructions.  See Intel 64 and IA-32
     1359;;; Architectures Software Development Manual, Volume 2B, entry for
     1360;;; NOP.
     1361(defstatic *x86-recommended-nops*
     1362  #(#()
     1363    #(#x90)
     1364    #(#x66 #x90)
     1365    #(#x0f #x1f #x00)
     1366    #(#x0f #x1f #x40 #x00)
     1367    #(#x0f #x1f #x44 #x00 #x00)
     1368    #(#x66 #x0f #x1f #x44 #x00 #x00)
     1369    #(#x0f #x1f #x80 #x00 #x00 #x00 #x00)
     1370    #(#x0f #x1f #x84 #x00 #x00 #x00 #x00 #x00)
     1371    ))
     1372
     1373(defstatic *x86-9-byte-nop* #(#x66 #x0f #x1f #x84 #x00 #x00 #x00 #x00 #x00))
    13741374
    13751375(defun frag-emit-nops (frag count)
    1376   (target-word-size-case
    1377    (32
    1378     (do* ((c count (- c 8)))
    1379          ((< c 8)
    1380           (let* ((v (svref *x86-32-bit-lap-nops* c)))
    1381             (dotimes (i c)
    1382               (frag-push-byte frag (svref v i)))))
    1383       (dotimes (i 8)
    1384         (frag-push-byte frag (svref *x86-32-bit-lap-nops-8* i)))))
    1385    (64
    1386     (let* ((nnops (ash (+ count 3) -2))
    1387            (len (floor count nnops))
    1388            (remains (- count (* nnops len))))
    1389       (dotimes (i remains)
    1390         (dotimes (k len) (frag-push-byte frag #x66))
    1391         (frag-push-byte frag #x90))
    1392       (do* ((i remains (1+ i)))
    1393            ((= i nnops))
    1394         (dotimes (k (1- len)) (frag-push-byte frag #x66))
    1395         (frag-push-byte frag #x90))))))
     1376  (do ((c count (- c 9)))
     1377      ((< c 9)
     1378       (let ((v (svref *x86-recommended-nops* c)))
     1379         (dotimes (i c)
     1380           (frag-push-byte frag (svref v i)))))
     1381    (dotimes (i 9)
     1382      (frag-push-byte frag (svref *x86-9-byte-nop* i)))))
    13961383 
    13971384(defun fill-for-alignment (frag-list)
  • trunk/source/lisp-kernel/pmcl-kernel.c

    r16394 r16630  
    16321632
    16331633  if (eax >= 1) {
     1634    int family;
     1635    int has_long_nop;
     1636
    16341637    eax = cpuid(1, &ebx, &ecx, &edx);
    16351638    cache_block_size = (ebx & 0xff00) >> 5;
    1636     if ((X86_REQUIRED_FEATURES & edx) == X86_REQUIRED_FEATURES) {
     1639
     1640    /* Does processor support multi-byte NOP (0x0f 0x1f)? */
     1641    family = (eax & 0xf00) >> 8;
     1642    has_long_nop = (family == 0x6 || family == 0xf);
     1643
     1644    if ((X86_REQUIRED_FEATURES & edx) == X86_REQUIRED_FEATURES && has_long_nop)
     1645    {
    16371646      return true;
    16381647    }
     1648
    16391649    /* It's very unlikely that SSE2 would be present and other things
    16401650       that we want wouldn't.  If they don't have MMX or CMOV either,
     
    16491659      fprintf(dbgout, "This CPU doesn't support the CMOV instruction\n");
    16501660    }
    1651    
     1661    if (has_long_nop == 0) {
     1662      fprintf(dbgout, "This CPU doesn't support the multi-byte form of NOP\n");
     1663    }
    16521664  }
    16531665  return false;
Note: See TracChangeset for help on using the changeset viewer.