1 //: jump to 16-bit offset
  2 
  3 //:: jump
  4 
  5 :(before "End Initialize Op Names")
  6 put_new(Name, "e9", "jump disp16 bytes away (jmp)");
  7 
  8 :(scenario jump_rel16)
  9 == 0x1
 10 # op  ModR/M  SIB   displacement  immediate
 11   e9                05 00                     # skip 1 instruction
 12   05                              00 00 00 01
 13   05                              00 00 00 02
 14 +run: inst: 0x00000001
 15 +run: jump 5
 16 +run: inst: 0x00000009
 17 -run: inst: 0x00000003
 18 
 19 :(before "End Single-Byte Opcodes")
 20 case 0xe9: {  // jump rel8
 21   const int16_t offset = imm16();
 22   trace(90, "run") << "jump " << offset << end();
 23   EIP += offset;
 24   break;
 25 }
 26 :(code)
 27 int16_t imm16() {
 28   int16_t result = next();
 29   result |= (next()<<8);
 30   return result;
 31 }
 32 
 33 //:: jump if equal/zero
 34 
 35 :(before "End Initialize Op Names")
 36 put_new(Name_0f, "84", "jump disp16 bytes away if equal, if ZF is set (jcc/jz/je)");
 37 
 38 :(scenario je_rel16_success)
 39 % ZF = true;
 40 == 0x1
 41 # op      ModR/M  SIB   displacement  immediate
 42   0f 84                 05 00                     # skip 1 instruction
 43   05                                  00 00 00 01
 44   05                                  00 00 00 02
 45 +run: inst: 0x00000001
 46 +run: jump 5
 47 +run: inst: 0x0000000a
 48 -run: inst: 0x00000005
 49 
 50 :(before "End Two-Byte Opcodes Starting With 0f")
 51 case 0x84: {  // jump rel16 if ZF
 52   const int8_t offset = imm16();
 53   if (ZF) {
 54     trace(90, "run") << "jump " << NUM(offset) << end();
 55     EIP += offset;
 56   }
 57   break;
 58 }
 59 
 60 :(scenario je_rel16_fail)
 61 % ZF = false;
 62 == 0x1
 63 # op      ModR/M  SIB   displacement  immediate
 64   0f 84                 05 00                     # skip 1 instruction
 65   05                                  00 00 00 01
 66   05                                  00 00 00 02
 67 +run: inst: 0x00000001
 68 +run: inst: 0x00000005
 69 +run: inst: 0x0000000a
 70 -run: jump 5
 71 
 72 //:: jump if not equal/not zero
 73 
 74 :(before "End Initialize Op Names")
 75 put_new(Name_0f, "85", "jump disp16 bytes away if not equal, if ZF is not set (jcc/jnz/jne)");
 76 
 77 :(scenario jne_rel16_success)
 78 % ZF = false;
 79 == 0x1
 80 # op      ModR/M  SIB   displacement  immediate
 81   0f 85                 05 00                     # skip 1 instruction
 82   05                                  00 00 00 01
 83   05                                  00 00 00 02
 84 +run: inst: 0x00000001
 85 +run: jump 5
 86 +run: inst: 0x0000000a
 87 -run: inst: 0x00000005
 88 
 89 :(before "End Two-Byte Opcodes Starting With 0f")
 90 case 0x85: {  // jump rel16 unless ZF
 91   const int8_t offset = imm16();
 92   if (!ZF) {
 93     trace(90, "run") << "jump " << NUM(offset) << end();
 94     EIP += offset;
 95   }
 96   break;
 97 }
 98 
 99 :(scenario jne_rel16_fail)
100 % ZF = true;
101 == 0x1
102 # op      ModR/M  SIB   displacement  immediate
103   0f 85                 05 00                     # skip 1 instruction
104   05                                  00 00 00 01
105   05                                  00 00 00 02
106 +run: inst: 0x00000001
107 +run: inst: 0x00000005
108 +run: inst: 0x0000000a
109 -run: jump 5
110 
111 //:: jump if greater
112 
113 :(before "End Initialize Op Names")
114 put_new(Name_0f, "8f", "jump disp16 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)");
115 
116 :(scenario jg_rel16_success)
117 % ZF = false;
118 % SF = false;
119 % OF = false;
120 == 0x1
121 # op      ModR/M  SIB   displacement  immediate
122   0f 8f                 05 00                     # skip 1 instruction
123   05                                  00 00 00 01
124   05                                  00 00 00 02
125 +run: inst: 0x00000001
126 +run: jump 5
127 +run: inst: 0x0000000a
128 -run: inst: 0x00000005
129 
130 :(before "End Two-Byte Opcodes Starting With 0f")
131 case 0x8f: {  // jump rel16 if !SF and !ZF
132   const int8_t offset = imm16();
133   if (!ZF && SF == OF) {
134     trace(90, "run") << "jump " << NUM(offset) << end();
135     EIP += offset;
136   }
137   break;
138 }
139 
140 :(scenario jg_rel16_fail)
141 % ZF = false;
142 % SF = true;
143 % OF = false;
144 == 0x1
145 # op      ModR/M  SIB   displacement  immediate
146   0f 8f                 05 00                     # skip 1 instruction
147   05                                  00 00 00 01
148   05                                  00 00 00 02
149 +run: inst: 0x00000001
150 +run: inst: 0x00000005
151 +run: inst: 0x0000000a
152 -run: jump 5
153 
154 //:: jump if greater or equal
155 
156 :(before "End Initialize Op Names")
157 put_new(Name_0f, "8d", "jump disp16 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)");
158 
159 :(scenario jge_rel16_success)
160 % SF = false;
161 % OF = false;
162 == 0x1
163 # op      ModR/M  SIB   displacement  immediate
164   0f 8d                 05 00                     # skip 1 instruction
165   05                                  00 00 00 01
166   05                                  00 00 00 02
167 +run: inst: 0x00000001
168 +run: jump 5
169 +run: inst: 0x0000000a
170 -run: inst: 0x00000005
171 
172 :(before "End Two-Byte Opcodes Starting With 0f")
173 case 0x8d: {  // jump rel16 if !SF
174   const int8_t offset = imm16();
175   if (SF == OF) {
176     trace(90, "run") << "jump " << NUM(offset) << end();
177     EIP += offset;
178   }
179   break;
180 }
181 
182 :(scenario jge_rel16_fail)
183 % SF = true;
184 % OF = false;
185 == 0x1
186 # op      ModR/M  SIB   displacement  immediate
187   0f 8d                 05 00                     # skip 1 instruction
188   05                                  00 00 00 01
189   05                                  00 00 00 02
190 +run: inst: 0x00000001
191 +run: inst: 0x00000005
192 +run: inst: 0x0000000a
193 -run: jump 5
194 
195 //:: jump if lesser
196 
197 :(before "End Initialize Op Names")
198 put_new(Name_0f, "8c", "jump disp16 bytes away if lesser, if SF != OF (jcc/jl/jnge)");
199 
200 :(scenario jl_rel16_success)
201 % ZF = false;
202 % SF = true;
203 % OF = false;
204 == 0x1
205 # op      ModR/M  SIB   displacement  immediate
206   0f 8c                 05 00                     # skip 1 instruction
207   05                                  00 00 00 01
208   05                                  00 00 00 02
209 +run: inst: 0x00000001
210 +run: jump 5
211 +run: inst: 0x0000000a
212 -run: inst: 0x00000005
213 
214 :(before "End Two-Byte Opcodes Starting With 0f")
215 case 0x8c: {  // jump rel16 if SF and !ZF
216   const int8_t offset = imm16();
217   if (SF != OF) {
218     trace(90, "run") << "jump " << NUM(offset) << end();
219     EIP += offset;
220   }
221   break;
222 }
223 
224 :(scenario jl_rel16_fail)
225 % ZF = false;
226 % SF = false;
227 % OF = false;
228 == 0x1
229 # op      ModR/M  SIB   displacement  immediate
230   0f 8c                 05 00                     # skip 1 instruction
231   05                                  00 00 00 01
232   05                                  00 00 00 02
233 +run: inst: 0x00000001
234 +run: inst: 0x00000005
235 +run: inst: 0x0000000a
236 -run: jump 5
237 
238 //:: jump if lesser or equal
239 
240 :(before "End Initialize Op Names")
241 put_new(Name_0f, "8e", "jump disp16 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)");
242 
243 :(scenario jle_rel16_equal)
244 % ZF = true;
245 % SF = false;
246 % OF = false;
247 == 0x1
248 # op      ModR/M  SIB   displacement  immediate
249   0f 8e                 05 00                     # skip 1 instruction
250   05                                  00 00 00 01
251   05                                  00 00 00 02
252 +run: inst: 0x00000001
253 +run: jump 5
254 +run: inst: 0x0000000a
255 -run: inst: 0x00000005
256 
257 :(scenario jle_rel16_lesser)
258 % ZF = false;
259 % SF = true;
260 % OF = false;
261 == 0x1
262 # op      ModR/M  SIB   displacement  immediate
263   0f 8e                 05 00                     # skip 1 instruction
264   05                                  00 00 00 01
265   05                                  00 00 00 02
266 +run: inst: 0x00000001
267 +run: jump 5
268 +run: inst: 0x0000000a
269 -run: inst: 0x00000005
270 
271 :(before "End Two-Byte Opcodes Starting With 0f")
272 case 0x8e: {  // jump rel16 if SF or ZF
273   const int8_t offset = imm16();
274   if (ZF || SF != OF) {
275     trace(90, "run") << "jump " << NUM(offset) << end();
276     EIP += offset;
277   }
278   break;
279 }
280 
281 :(scenario jle_rel16_greater)
282 % ZF = false;
283 % SF = false;
284 % OF = false;
285 == 0x1
286 # op      ModR/M  SIB   displacement  immediate
287   0f 8e                 05 00                     # skip 1 instruction
288   05                                  00 00 00 01
289   05                                  00 00 00 02
290 +run: inst: 0x00000001
291 +run: inst: 0x00000005
292 +run: inst: 0x0000000a
293 -run: jump 5