Have sign-extend-complex deal correctly with bytes of size 0.
[movitz-ia-x86.git] / instr-misc.lisp
blob7967a7b0babff245df460f3c5739ff65ede1aa85
1 ;;;;------------------------------------------------------------------
2 ;;;;
3 ;;;; Copyright (C) 20012000, 2002-2004,
4 ;;;; Department of Computer Science, University of Tromso, Norway
5 ;;;;
6 ;;;; Filename: instr-misc.lisp
7 ;;;; Description: Miscellaneous x86 instructions.
8 ;;;; Author: Frode Vatvedt Fjeld <frodef@acm.org>
9 ;;;; Created at: Fri Jan 28 19:25:27 2000
10 ;;;; Distribution: See the accompanying file COPYING.
11 ;;;;
12 ;;;; $Id: instr-misc.lisp,v 1.2 2004/01/16 11:54:14 ffjeld Exp $
13 ;;;;
14 ;;;;------------------------------------------------------------------
16 (in-package "IA-X86-INSTR")
18 ;;; ----------------------------------------------------------------
19 ;;; LEA [IISR page 11-255]
20 ;;; ----------------------------------------------------------------
22 (def-instr lea (instruction))
23 (def-instr leal (lea)
24 (:r #x8d (r/m32 r32) :operand-mode :32-bit)
25 (:r #x8d (r/m16 r32) :operand-mode :32-bit))
26 (def-instr leaw (lea)
27 (:r #x8d (r/m16 r16) :operand-mode :16-bit)
28 (:r #x8d (r/m32 r16) :operand-mode :16-bit))
30 ;;; ----------------------------------------------------------------
31 ;;; LDS/LES/LFS/LGS/LSS -- Load Far Pointer
32 ;;; ----------------------------------------------------------------
34 (def-instr lds (instruction))
35 (def-instr ldsw (lds) (:r #xC5 (r16 r/m16) :indirect t :operand-mode :16-bit))
36 (def-instr ldsl (lds) (:r #xC5 (r32 r/m32) :indirect t :operand-mode :32-bit))
38 (def-instr les (instruction))
39 (def-instr lesw (les) (:r #xC4 (r16 r/m16) :indirect t :operand-mode :16-bit))
40 (def-instr lesl (les) (:r #xC4 (r32 r/m32) :indirect t :operand-mode :32-bit))
42 (def-instr lss (instruction))
43 (def-instr lssw (lss) (:r #c(#x0fb2 2) (r16 r/m16) :indirect t :operand-mode :16-bit))
44 (def-instr lssl (lss) (:r #c(#x0fb2 2) (r32 r/m32) :indirect t :operand-mode :32-bit))
46 (def-instr lfs (instruction))
47 (def-instr lfsw (lfs) (:r #c(#x0fb4 2) (r16 r/m16) :indirect t :operand-mode :16-bit))
48 (def-instr lfsl (lfs) (:r #c(#x0fb4 2) (r32 r/m32) :indirect t :operand-mode :32-bit))
50 (def-instr lgs (instruction))
51 (def-instr lgsw (lgs) (:r #c(#x0fb5 2) (r16 r/m16) :indirect t :operand-mode :16-bit))
52 (def-instr lgsl (lgs) (:r #c(#x0fb5 2) (r32 r/m32) :indirect t :operand-mode :32-bit))
54 ;;; ----------------------------------------------------------------
55 ;;; XCHG
56 ;;; ----------------------------------------------------------------
58 (def-instr xchg (instruction))
60 (def-instr xchgb (xchg)
61 (:r #x86 (r8 r/m8))
62 (:r #x86 (r/m8 r8)))
64 (def-instr xchgw (xchg)
65 (:+ #x90 0 (ax +r16) :operand-mode :16-bit)
66 (:+ #x90 0 (+r16 ax) :operand-mode :16-bit)
67 (:r #x87 (r/m16 r16) :operand-mode :16-bit)
68 (:r #x87 (r16 r/m16) :operand-mode :16-bit))
70 (def-instr xchgl (xchg)
71 (:+ #x90 0 (eax +r32) :operand-mode :32-bit)
72 (:+ #x90 0 (+r32 eax) :operand-mode :32-bit)
73 (:r #x87 (r/m32 r32) :operand-mode :32-bit)
74 (:r #x87 (r32 r/m32) :operand-mode :32-bit))
76 ;;; ----------------------------------------------------------------
77 ;;; INTn [IISR page 11-216]
78 ;;; ----------------------------------------------------------------
80 (def-instr break (instruction) (:simple #xcc))
81 (def-instr into (instruction) (:simple #xce))
82 (def-instr int (instruction) (:plain #xcd (0 1) (imm8)))
84 ;;; ----------------------------------------------------------------
85 ;;; In (Input from IO port)
86 ;;; ----------------------------------------------------------------
88 (def-instr in (instruction))
89 (def-instr inb (in)
90 (:plain #xE4 (0 1) (imm8 al))
91 (:plain #xEC (0 0) (dx al)))
93 (def-instr inw (in)
94 (:plain #xE5 (0 1) (imm8 ax) :operand-mode :16-bit)
95 (:plain #xED (0 0) (dx ax) :operand-mode :16-bit))
97 (def-instr inl (in)
98 (:plain #xE5 (0 1) (imm8 eax) :operand-mode :32-bit)
99 (:plain #xED (0 0) (dx eax) :operand-mode :32-bit))
101 (def-instr insb (instruction) (:simple #x6c))
102 (def-instr insw (instruction) (:simple #x6d :operand-mode :16-bit))
103 (def-instr insd (instruction) (:simple #x6d :operand-mode :32-bit))
105 ;;; ----------------------------------------------------------------
106 ;;; Out (Output to IO port)
107 ;;; ----------------------------------------------------------------
109 (def-instr out (instruction))
110 (def-instr outb (out)
111 (:plain #xE6 (0 1) (al imm8))
112 (:plain #xEE (0 0) (al dx)))
114 (def-instr outw (out)
115 (:plain #xE7 (0 1) (ax imm8) :operand-mode :16-bit)
116 (:plain #xEF (0 0) (ax dx) :operand-mode :16-bit))
118 (def-instr outl (out)
119 (:plain #xE7 (0 1) (eax imm8) :operand-mode :32-bit)
120 (:plain #xEF (0 0) (eax dx) :operand-mode :32-bit))
122 (def-instr outsb (instruction) (:simple #x6e))
123 (def-instr outsw (instruction) (:simple #x6f :operand-mode :16-bit))
124 (def-instr outsd (instruction) (:simple #x6f :operand-mode :32-bit))
126 ;;; ----------------------------------------------------------------
127 ;;; ASCII related instructions
128 ;;; ----------------------------------------------------------------
130 (def-instr aaa (instruction) (:simple #x37))
131 (def-instr aas (instruction) (:simple #x3f))
133 (def-instr aad (instruction)
134 (:plain #xd5 (0 1) (imm8 ax))
135 (:simple #c(#xd50a 2) :priority -5)) ; imm8 defaults to 10.
136 (def-instr aam (instruction)
137 (:plain #xd4 (0 1) (imm8 ax))
138 (:simple #c(#xd40a 2) :priority -5)) ; imm8 defaults to 10.
140 ;;; ----------------------------------------------------------------
141 ;;; Decimal related instructions
142 ;;; ----------------------------------------------------------------
144 (def-instr daa (instruction) (:simple #x27))
145 (def-instr das (instruction) (:simple #x2f))
147 ;;; ----------------------------------------------------------------
148 ;;; Various simple instructions
149 ;;; ----------------------------------------------------------------
151 (def-instr clc (instruction) (:simple #xF8)) ; clear carry flag
152 (def-instr stc (instruction) (:simple #xF9)) ; set carry flag
153 (def-instr cld (instruction) (:simple #xFC)) ; clear direction flag
154 (def-instr std (instruction) (:simple #xFD)) ; set direction flag
155 (def-instr cli (instruction) (:simple #xFA)) ; clear interrupt flag
156 (def-instr sti (instruction) (:simple #xFB)) ; set interrupt flag
157 (def-instr cmc (instruction) (:simple #xf5)) ; complement carry flag
158 (def-instr clts (instruction) (:simple #c(#x0f06 2))) ; clear task-switched flag in CR0
159 (def-instr lahf (instruction) (:simple #x9f :operands (ah))) ; load status flags into %AH
160 (def-instr cpuid (instruction) (:simple #c(#x0fa2 2))) ; CPU identification
162 (def-instr halt (instruction) (:simple #xf4 :priority 10))
163 (def-instr nop (instruction) (:simple #x90 :priority 10)) ; needs priority over XCHG %EAX %EAX
165 (def-instr invd (instruction) (:simple #c(#x0f08 2))) ; invalidate internal caches
167 ;;; ----------------------------------------------------------------
168 ;;; XXX
169 ;;; ----------------------------------------------------------------
171 (def-instr arpl (instruction) (:r #x63 (r16 r/m16)))
173 (def-instr bound (instruction)
174 (:r #x62 (r/m16 r16) :operand-mode :16-bit)
175 (:r #x62 (r/m32 r32) :operand-mode :32-bit))
177 (def-instr sahf (instruction) (:simple #x9E :operands (ah))) ; Load SF, ZF, AF, PF, CF from AH into EFLAGS
179 (def-instr xlatb (instruction) (:simple #xD7 :operands (ebx al al))) ; Exchange AL with [EBX + AL]
182 (def-instr cbtw (instruction)
183 (:simple #x98 :operands (al ax) :operand-mode :16-bit)) ; sign-extend al into ah (ax)
184 (def-instr cwtl (instruction)
185 (:simple #x98 :operands (ax eax) :operand-mode :32-bit)) ; sign-extend ax into eax
186 (def-instr cwd (instruction)
187 (:simple #x99 :operands (ax dx) :operand-mode :16-bit)) ; sign-extend ax into dx
188 (def-instr cdq (instruction)
189 (:simple #x99 :operands (eax edx) :operand-mode :32-bit)) ; sign-extend eax into edx
191 (def-instr bswap (instruction) (:+ #c(#x0fc8 2) 0 (+r32)))
194 ;;; Store Local Descriptor Table Register
196 (def-instr sldt (instruction)
197 (:digit (#x0f00 0) 0 (r/m16) :operand-mode :16-bit)
198 (:digit (#x0f00 0) 0 (r/m32) :operand-mode :32-bit))
200 ;;; Store Global/Interrupt Descriptor Table Register
202 (def-instr sgdt (instruction)
203 (:digit (#x0f01 0) 0 (m) :indirect t))
205 (def-instr sidt (instruction)
206 (:digit (#x0f01 1) 0 (m) :indirect t))
208 ;;; Load Access Rights Byte
210 (def-instr lar (instruction)
211 (:r #x0f02 (r/m16 r16) :operand-mode :16-bit)
212 (:r #x0f02 (r/m32 r32) :operand-mode :32-bit))
214 ;;; Load Segment Limit
216 (def-instr lsl (instruction)
217 (:r #x0f03 (r/m16 r16) :operand-mode :16-bit)
218 (:r #x0f03 (r/m32 r32) :operand-mode :32-bit))
220 ;;; Write-Back and Invalidate Cache
222 (def-instr wbinvd (instruction) (:simple #x0f09))
224 ;;; Write to Model Specific Register
226 (def-instr wrmsr (instruction) (:simple #x0f30)) ; Write EDX:EAX to MSR in ECX
228 ;;; Read from Model Specific Register
230 (def-instr rdmsr (instruction) (:simple #x0f32)) ; Read from MSR in ECX into EDX:EAX
232 ;;; Read Time-Stamp Counter
234 (def-instr rdtsc (instruction) (:simple #x0f31)) ; Read into EDX:EAX
236 ;;; Read Performance-Monitoring Counters
238 (def-instr rdpmc (instruction) (:simple #x0f33)) ; Read counter in ECX into EDX:EAX
240 ;;; Fast Transition to/from System Call
242 (def-instr sysenter (instruction) (:simple #x0f34))
243 (def-instr sysexit (instruction) (:simple #x0f35))
245 ;;; Load Global/Interrupt Descriptor Table Register
247 (def-instr lgdt (instruction) (:digit (#x0f01 2) 0 (r/m32) :indirect t))
249 (def-instr lidt (instruction) (:digit (#x0f01 3) 0 (r/m32)))
251 ;;; Load Local Descriptor Table Register
253 (def-instr lldt (instruction) (:digit (#x0f00 2) 0 (r/m16)))
255 ;;; Load Machine Status Word
256 (def-instr lmsw (instruction) (:digit (#x0f01 6) 0 (r/m16)))
259 ;;; ----------------------------------------------------------------
260 ;;; SETcc -- Set Byte on Condition
261 ;;; ----------------------------------------------------------------
263 (def-instr set (instruction))
265 (def-instr seta (set) (:set #x0f97)) ; if above
266 (def-instr setae (set) (:set #x0f93 :priority 10)) ; if above or equal
267 (def-instr setb (set) (:set #x0f92 :priority 10)) ; if below
268 (def-instr setbe (set) (:set #x0f96)) ; if below or equal
269 (def-instr setc (set) (:set #x0f92 :priority 10)) ; if carry
270 (def-instr sete (set) (:set #x0f94)) ; if equal
271 (def-instr setg (set) (:set #x0f9f :priority 10)) ; if greater
272 (def-instr setge (set) (:set #x0f9d :priority 10)) ; if greater or equal
273 (def-instr setl (set) (:set #x0f9c)) ; if less
274 (def-instr setle (set) (:set #x0f9e)) ; if less or equal
275 (def-instr setna (set) (:set #x0f96)) ; if not above
276 (def-instr setnae (set) (:set #x0f92)) ; if not above or equal
277 (def-instr setnb (set) (:set #x0f93)) ; if not below
278 (def-instr setnbe (set) (:set #x0f97)) ; if not below or equal
279 (def-instr setnc (set) (:set #x0f93 :priority 20)) ; if not carry
280 (def-instr setne (set) (:set #x0f95 :priority 10)) ; if not equal
281 (def-instr setng (set) (:set #x0f9e)) ; if not greater
282 (def-instr setnge (set) (:set #x0f9c)) ; if not greater or equal
283 (def-instr setnl (set) (:set #x0f9d)) ; if not less
284 (def-instr setnle (set) (:set #x0f9f)) ; if not less or equal
285 (def-instr setno (set) (:set #x0f91)) ; if not overflow
286 (def-instr setnp (set) (:set #x0f9b)) ; if not parity
287 (def-instr setns (set) (:set #x0f99)) ; if not sign
288 (def-instr setnz (set) (:set #x0f95)) ; if not zero
289 (def-instr seto (set) (:set #x0f90)) ; if overflow
290 (def-instr setp (set) (:set #x0f9a)) ; if parity
291 (def-instr setpe (set) (:set #x0f9a :priority 10)) ; if parity even
292 (def-instr setpo (set) (:set #x0f9b :priority 10)) ; if parity odd
293 (def-instr sets (set) (:set #x0f98)) ; if sign
294 (def-instr setz (set) (:set #x0f94)) ; if zero
297 ;;; ----------------------------------------------------------------
298 ;;; PREFETCH
299 ;;; ----------------------------------------------------------------
301 (def-instr prefetch-t0 (instruction) ; t0 hint
302 (:digit (#x0f18 1) 0 (r/m8) :indirect t))
304 (def-instr prefetch-t1 (instruction) ; t1 hint
305 (:digit (#x0f18 2) 0 (r/m8) :indirect t))
307 (def-instr prefetch-t2 (instruction) ; t2 hint
308 (:digit (#x0f18 3) 0 (r/m8) :indirect t))
310 (def-instr prefetch-nta (instruction) ; nta hint
311 (:digit (#x0f18 0) 0 (r/m8) :indirect t))
314 ;;; Store Fence
316 (def-instr sfence (instruction) (:simple #c(#x0faef8 3)))