[yalo commit] r137 - trunk/cc wiki

0 views
Skip to first unread message

codesite...@google.com

unread,
Mar 3, 2009, 9:00:26 AM3/3/09
to yalo-...@googlegroups.com
Author: yujian.zhang
Date: Tue Mar 3 05:26:38 2009
New Revision: 137

Modified:
trunk/cc/lap.lisp
trunk/cc/test-cc.lisp
trunk/cc/x86-64-syntax.lisp
wiki/AssemblyX64X.wiki

Log:
Add instruction xchg.

Modified: trunk/cc/lap.lisp
==============================================================================
--- trunk/cc/lap.lisp (original)
+++ trunk/cc/lap.lisp Tue Mar 3 05:26:38 2009
@@ -107,64 +107,72 @@
(rep . #xf3) (repe . #xf3) (repz . #xf3))
"Prefix mapping table.")

-(defun encode (e cursor bits)
+(defun encode (e* cursor bits)
"Opcode encoding, including pseudo instructions like db/dw."
- (acond
- ((assoc* (car e) *prefix-mapping*)
- (cons it (encode (cdr e) (1+ cursor) bits)))
- ((assoc* e (x86-64-syntax bits) :test #'equal)
- ;; Instructions with exact match, e.g. instructions without
- ;; operands (like nop, hlt), or special instructions like int 3.
- ;; copy-list is necessary since syntax table is LITERAL.
- (if (member (car it) '(o16 o32 a16 a32))
- (append (size-prefix (car it) bits) (copy-list (cdr it)))
- (copy-list it)))
- ((assoc e (x86-64-syntax bits)
- :test #'(lambda (x y)
- (and (> (length y) 1)
- (equal (subseq x 0 2) (subseq y 0 2))
- (member (elt x 1) '(al ax eax rax))
- (numberp (elt x 2)))))
- ;; Some registers are explicitly given as destination operand,
- ;; e.g. (add al imm8).
- (encode-complex e (canonical-type (car it)) (cdr it) cursor bits))
- ((assoc* e (x86-64-syntax bits)
- :test #'(lambda (x y)
- (and (member (car x) '(shl shr))
- (> (length y) 2)
- (= (length x) (length y))
- (eq (car x) (car y))
- (eq (car (last x)) (car (last y)))
- (eq (operand-type (car (last x 2))) (car (last
y 2)))
- (if (= (length x) 3)
- t
- (eq (second x) (second y)))
- (member (car (last x)) '(1 cl)))))
- ;; Special case for (shl/shr r/m8/16 1/cl).
- (encode-complex (butlast e) (butlast (instruction-type e)) it cursor
bits))
- ((cc-instruction? e 'cmov) ; CMOVcc.
- (declare (ignore it))
- (cc-encode e 'cmov cursor bits))
- ((cc-instruction? e 'j) ; Jcc.
- (declare (ignore it))
- (cc-encode e 'j cursor bits))
- (t
- (declare (ignore it))
- (case (car e)
- ;; Pseudo instructions.
- ((db dw dd dq)
- (let ((val (mklist (nth (1- (length e)) e))))
- (mapcan #'(lambda (v)
- (ecase (car e)
- (db (cond
- ((stringp v) (string->bytes v))
- (t (try-encode-bytes v 1))))
- (dw (try-encode-bytes v 2))
- (dd (try-encode-bytes v 4))
- (dq (try-encode-bytes v 8))))
- val)))
- ;; Normal instructions.
- (t (match-n-encode e cursor bits))))))
+ (let ((e (if (and (eq (car e*) 'xchg)
+ (member (second e*) '(ax eax rax)))
+ (list (car e*) (third e*) (second e*))
+ e*)))
+ (acond
+ ((assoc* (car e) *prefix-mapping*)
+ (cons it (encode (cdr e) (1+ cursor) bits)))
+ ((assoc* e (x86-64-syntax bits) :test #'equal)
+ ;; Instructions with exact match, e.g. instructions without
+ ;; operands (like nop, hlt), or special instructions like int 3.
+ ;; copy-list is necessary since syntax table is LITERAL.
+ (if (member (car it) '(o16 o32 a16 a32))
+ (append (size-prefix (car it) bits) (copy-list (cdr it)))
+ (copy-list it)))
+ ((assoc e (x86-64-syntax bits)
+ :test #'(lambda (x y)
+ (and (> (length y) 1)
+ (eq (car x) (car y))
+ (or (and (member (elt x 1) '(al ax eax rax))
+ (numberp (elt x 2))
+ (eq (second x) (second y)))
+ (and (eq (car x) 'xchg)
+ (member (third x) '(ax eax rax))
+ (eq (third x) (third y)))))))
+ ;; Some registers are explicitly given as destination operand,
+ ;; e.g. (add al imm8).
+ (encode-complex e (canonical-type (car it)) (cdr it) cursor bits))
+ ((assoc* e (x86-64-syntax bits)
+ :test #'(lambda (x y)
+ (and (member (car x) '(shl shr))
+ (> (length y) 2)
+ (= (length x) (length y))
+ (eq (car x) (car y))
+ (eq (car (last x)) (car (last y)))
+ (eq (operand-type (car (last x 2))) (car
(last y 2)))
+ (if (= (length x) 3)
+ t
+ (eq (second x) (second y)))
+ (member (car (last x)) '(1 cl)))))
+ ;; Special case for (shl/shr r/m8/16 1/cl).
+ (encode-complex (butlast e) (butlast (instruction-type e)) it cursor
bits))
+ ((cc-instruction? e 'cmov) ; CMOVcc.
+ (declare (ignore it))
+ (cc-encode e 'cmov cursor bits))
+ ((cc-instruction? e 'j) ; Jcc.
+ (declare (ignore it))
+ (cc-encode e 'j cursor bits))
+ (t
+ (declare (ignore it))
+ (case (car e)
+ ;; Pseudo instructions.
+ ((db dw dd dq)
+ (let ((val (mklist (nth (1- (length e)) e))))
+ (mapcan #'(lambda (v)
+ (ecase (car e)
+ (db (cond
+ ((stringp v) (string->bytes v))
+ (t (try-encode-bytes v 1))))
+ (dw (try-encode-bytes v 2))
+ (dd (try-encode-bytes v 4))
+ (dq (try-encode-bytes v 8))))
+ val)))
+ ;; Normal instructions.
+ (t (match-n-encode e cursor bits)))))))

(defun match-n-encode (e cursor bits &optional (cc-code 0))
"Match instruction and encode it."

Modified: trunk/cc/test-cc.lisp
==============================================================================
--- trunk/cc/test-cc.lisp (original)
+++ trunk/cc/test-cc.lisp Tue Mar 3 05:26:38 2009
@@ -231,6 +231,18 @@
(xadd cx dx)
(xadd edi edx)
(xadd rcx r10)
+ (xchg ax bx)
+ (xchg cx ax)
+ (xchg eax ebx)
+ (xchg ecx eax)
+ (xchg rax rbx)
+ (xchg rcx rax)
+ ;; (xchg a b) is equivalent to NASM's xchg b, a.
+ ;; They are semantically equivalent anyway.
+ (xchg al cl)
+ (xchg cx bx)
+ (xchg edx ebx)
+ (xchg r10 r15)

(equ hi 4)
(dw meta-msg msg)
@@ -243,17 +255,18 @@
"Miscellaneous instructions.")

(defparameter *misc-code*
- '(232 159 0 248 252 250 244 228 3 229 4 236 237 204 205 16 116 254
- 235 252 15 1 22 162 124 15 1 30 162 124 15 0 210 15 0 22 162 124
- 172 173 226 230 180 9 187 13 0 137 200 137 30 162 124 139 14 123
- 28 199 6 162 124 123 0 142 195 140 200 144 230 3 231 4 238 239 81
+ '(232 179 0 248 252 250 244 228 3 229 4 236 237 204 205 16 116 254
+ 235 252 15 1 22 182 124 15 1 30 182 124 15 0 210 15 0 22 182 124
+ 172 173 226 230 180 9 187 13 0 137 200 137 30 182 124 139 14 123
+ 28 199 6 182 124 123 0 142 195 140 200 144 230 3 231 4 238 239 81
14 22 30 6 90 23 31 7 243 164 243 165 243 102 165 195 249 253 251
170 171 15 203 72 15 200 73 15 202 102 15 71 195 15 66 194 73 15
68 210 15 176 209 102 15 177 209 15 177 215 76 15 177 209 15 199
- 11 72 15 199 11 15 130 20 0 0 0 15 5 15 7 15 192 209 102 15 193
- 209 15 193 215 76 15 193 209 162 124 72 101 108 108 111 32 87 111
- 114 108 100 33 32 0 0 0 85 170 64 226 1 0 67 104 120 0 0 0 230 130
- 217 250 11 0))
+ 11 72 15 199 11 15 130 40 0 0 0 15 5 15 7 15 192 209 102 15 193
+ 209 15 193 215 76 15 193 209 102 147 102 145 147 145 72 147 72 145
+ 134 200 102 135 217 135 218 77 135 250 182 124 72 101 108 108 111
+ 32 87 111 114 108 100 33 32 0 0 0 85 170 64 226 1 0 67 104 120 0 0
+ 0 230 130 217 250 11 0))

(defparameter *address-asm*
'((org #x7c00)

Modified: trunk/cc/x86-64-syntax.lisp
==============================================================================
--- trunk/cc/x86-64-syntax.lisp (original)
+++ trunk/cc/x86-64-syntax.lisp Tue Mar 3 05:26:38 2009
@@ -171,9 +171,17 @@
((test word m (imm16 imm8)) . (#xf7 /0 iw))
((test (r/m8 r8 m) r8) . (#x84 /r))
((test (r/m16 r16 m) r16) . (#x85 /r))
- ((xadd (r/m8 r8 m) r8) . (#x0f #xc0 /r))
- ((xadd (r/m16 r16 m) r16) . (o16 #x0f #xc1 /r))
- ((xadd (r/m32 r32 m) r32) . (o32 #x0f #xc1 /r))
+ ((xadd (r/m8 r8 m) r8) . (#x0f #xc0 /r))
+ ((xadd (r/m16 r16 m) r16) . (o16 #x0f #xc1 /r))
+ ((xadd (r/m32 r32 m) r32) . (o32 #x0f #xc1 /r))
+ ((xchg r16 ax) . (o16 (+ #x90 r)))
+ ((xchg r32 eax) . (o32 (+ #x90 r)))
+ ((xchg (r/m8 r8 m) r8) . (#x86 /r))
+ ((xchg r8 (r/m8 r8 m)) . (#x86 /r))
+ ((xchg (r/m16 r16 m) r16) . (o16 #x87 /r))
+ ((xchg r16 (r/m16 r16 m)) . (o16 #x87 /r))
+ ((xchg (r/m32 r32 m) r32) . (o32 #x87 /r))
+ ((xchg r32 (r/m32 r32 m)) . (o32 #x87 /r))
,@(arith-syntax-1 'xor nil))
"Valid for both 16-bit and 64-bit modes.")

@@ -213,6 +221,9 @@
((syscall) . (#x0f #x05))
((sysret) . (#x0f #x07))
((xadd (r/m64 r64 m) r64) . (#x0f #xc1 /r))
+ ((xchg r64 rax) . ((+ #x90 r)))
+ ((xchg (r/m64 r64 m) r64) . (#x87 /r))
+ ((xchg r64 (r/m64 r64 m)) . (#x87 /r))
,@(arith-syntax-1 'xor t)))

(defparameter *x86-64-syntax-16/32-bit*

Modified: wiki/AssemblyX64X.wiki
==============================================================================
--- wiki/AssemblyX64X.wiki (original)
+++ wiki/AssemblyX64X.wiki Tue Mar 3 05:26:38 2009
@@ -14,6 +14,30 @@

--------

+= xchg: Exchange =
+
+|| Instruction || Opcode || 64-Bit Mode || 16/32-Bit Mode ||
Description ||
+|| xchg ax r16 || o16 90+r || Valid || Valid ||
Exchange ax with r16 ||
+|| xchg r16 ax || o16 90+r || Valid || Valid ||
Exchange ax with r16 ||
+|| xchg eax r32 || o32 90+r || Valid || Valid ||
Exchange eax with r32 ||
+|| xchg r32 eax || o32 90+r || Valid || Valid ||
Exchange eax with r32 ||
+|| xchg rax r64 || 90+r || Valid || ~~N.E.~~ ||
Exchange rax with r64 ||
+|| xchg r64 rax || 90+r || Valid || ~~N.E.~~ ||
Exchange rax with r64 ||
+|| xchg r/m8 r8 || 86 /r || Valid || Valid ||
Exchange r/m8 with r8 ||
+|| xchg r8 r/m8 || 86 /r || Valid || Valid ||
Exchange r/m8 with r8 ||
+|| xchg r/m16 r16 || o16 87 /r || Valid || Valid ||
Exchange r/m16 with r16 ||
+|| xchg r16 r/m16 || o16 87 /r || Valid || Valid ||
Exchange r/m16 with r16 ||
+|| xchg r/m32 r32 || o32 87 /r || Valid || Valid ||
Exchange r/m32 with r32 ||
+|| xchg r32 r/m32 || o32 87 /r || Valid || Valid ||
Exchange r/m32 with r32 ||
+|| xchg r/m64 r64 || 87 /r || Valid || ~~N.E.~~ ||
Exchange r/m64 with r64 ||
+|| xchg r64 r/m64 || 87 /r || Valid || ~~N.E.~~ ||
Exchange r/m64 with r64 ||
+
+Note that when a memory operand is referenced, lock protocal is
+automatically implemented, regardless whether LOCK prefix is used or
+not. This may has impact on performance.
+
+--------
+
= xor: Logical Exclusive OR =

|| Instruction || Opcode || 64-Bit Mode || 16/32-Bit Mode ||
Description ||

Reply all
Reply to author
Forward
0 new messages