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