ytljit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +29 -0
- data/Rakefile +22 -0
- data/ext/code_alloc.c +266 -0
- data/ext/extconf.rb +3 -0
- data/ext/ytljit.c +527 -0
- data/ext/ytljit.h +285 -0
- data/lib/ytljit/asm.rb +205 -0
- data/lib/ytljit/asmext.rb +199 -0
- data/lib/ytljit/asmext_x64.rb +212 -0
- data/lib/ytljit/asmext_x86.rb +128 -0
- data/lib/ytljit/asmutil.rb +182 -0
- data/lib/ytljit/codespace.rb +92 -0
- data/lib/ytljit/error.rb +7 -0
- data/lib/ytljit/instruction.rb +138 -0
- data/lib/ytljit/instruction_ia.rb +1298 -0
- data/lib/ytljit/instruction_x64.rb +41 -0
- data/lib/ytljit/instruction_x86.rb +11 -0
- data/lib/ytljit/marshal.rb +133 -0
- data/lib/ytljit/matcher.rb +235 -0
- data/lib/ytljit/rubyvm.rb +63 -0
- data/lib/ytljit/struct.rb +125 -0
- data/lib/ytljit/type.rb +112 -0
- data/lib/ytljit/util.rb +63 -0
- data/lib/ytljit/vm.rb +1649 -0
- data/lib/ytljit/vm_codegen.rb +491 -0
- data/lib/ytljit/vm_inline_method.rb +85 -0
- data/lib/ytljit/vm_inspect.rb +74 -0
- data/lib/ytljit/vm_sendnode.rb +561 -0
- data/lib/ytljit/vm_trans.rb +508 -0
- data/lib/ytljit/vm_type.rb +299 -0
- data/lib/ytljit/vm_type_gen.rb +158 -0
- data/lib/ytljit/vm_typeinf.rb +98 -0
- data/lib/ytljit.rb +46 -0
- data/test/asmsample.rb +117 -0
- data/test/cstest.rb +61 -0
- data/test/marshaltest.rb +27 -0
- data/test/test_assemble.rb +148 -0
- data/test/test_assemble2.rb +286 -0
- data/test/test_codespace.rb +102 -0
- data/test/test_typeinf.rb +21 -0
- data/test/tivmtest.rb +54 -0
- data/test/vmtest.rb +59 -0
- data/test/vmtest2.rb +41 -0
- data/test/vmtest3.rb +22 -0
- data/test/vmtest_compile_only.rb +41 -0
- data/test/vmtest_execute_only.rb +22 -0
- metadata +121 -0
@@ -0,0 +1,1298 @@
|
|
1
|
+
module YTLJit
|
2
|
+
|
3
|
+
class OpReg8<OpRegistor
|
4
|
+
end
|
5
|
+
|
6
|
+
class OpAL<OpReg8
|
7
|
+
def reg_no
|
8
|
+
0
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_as
|
12
|
+
"%al"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class OpCL<OpReg8
|
17
|
+
def reg_no
|
18
|
+
1
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_as
|
22
|
+
"%cl"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class OpDL<OpReg8
|
27
|
+
def reg_no
|
28
|
+
2
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_as
|
32
|
+
"%dl"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class OpBL<OpReg8
|
37
|
+
def reg_no
|
38
|
+
3
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_as
|
42
|
+
"%bl"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class OpReg32<OpRegistor
|
47
|
+
end
|
48
|
+
|
49
|
+
class OpEAX<OpReg32
|
50
|
+
def reg_no
|
51
|
+
0
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_as
|
55
|
+
"%eax"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class OpECX<OpReg32
|
60
|
+
def reg_no
|
61
|
+
1
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_as
|
65
|
+
"%ecx"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class OpEDX<OpReg32
|
70
|
+
def reg_no
|
71
|
+
2
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_as
|
75
|
+
"%edx"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class OpEBX<OpReg32
|
80
|
+
def reg_no
|
81
|
+
3
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_as
|
85
|
+
"%ebx"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class OpESP<OpReg32
|
90
|
+
def reg_no
|
91
|
+
4
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_as
|
95
|
+
"%esp"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class OpEBP<OpReg32
|
100
|
+
def reg_no
|
101
|
+
5
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_as
|
105
|
+
"%ebp"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class OpESI<OpReg32
|
110
|
+
def reg_no
|
111
|
+
6
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_as
|
115
|
+
"%esi"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class OpEDI<OpReg32
|
120
|
+
def reg_no
|
121
|
+
7
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_as
|
125
|
+
"%edi"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class OpReg64<OpRegistor
|
130
|
+
end
|
131
|
+
|
132
|
+
class OpRAX<OpReg64
|
133
|
+
def reg_no
|
134
|
+
0
|
135
|
+
end
|
136
|
+
|
137
|
+
def to_as
|
138
|
+
"%rax"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class OpRCX<OpReg64
|
143
|
+
def reg_no
|
144
|
+
1
|
145
|
+
end
|
146
|
+
|
147
|
+
def to_as
|
148
|
+
"%rcx"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class OpRDX<OpReg64
|
153
|
+
def reg_no
|
154
|
+
2
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_as
|
158
|
+
"%rdx"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class OpRBX<OpReg64
|
163
|
+
def reg_no
|
164
|
+
3
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_as
|
168
|
+
"%rbx"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class OpRSP<OpReg64
|
173
|
+
def reg_no
|
174
|
+
4
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_as
|
178
|
+
"%rsp"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
class OpRBP<OpReg64
|
183
|
+
def reg_no
|
184
|
+
5
|
185
|
+
end
|
186
|
+
|
187
|
+
def to_as
|
188
|
+
"%rbp"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
class OpRSI<OpReg64
|
193
|
+
def reg_no
|
194
|
+
6
|
195
|
+
end
|
196
|
+
|
197
|
+
def to_as
|
198
|
+
"%rsi"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class OpRDI<OpReg64
|
203
|
+
def reg_no
|
204
|
+
7
|
205
|
+
end
|
206
|
+
|
207
|
+
def to_as
|
208
|
+
"%rdi"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
class OpR8<OpReg64
|
213
|
+
def reg_no
|
214
|
+
8
|
215
|
+
end
|
216
|
+
|
217
|
+
def to_as
|
218
|
+
"%r8"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
class OpR9<OpReg64
|
223
|
+
def reg_no
|
224
|
+
9
|
225
|
+
end
|
226
|
+
|
227
|
+
def to_as
|
228
|
+
"%r9"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
class OpR10<OpReg64
|
233
|
+
def reg_no
|
234
|
+
10
|
235
|
+
end
|
236
|
+
|
237
|
+
def to_as
|
238
|
+
"%r10"
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
class OpR11<OpReg64
|
243
|
+
def reg_no
|
244
|
+
11
|
245
|
+
end
|
246
|
+
|
247
|
+
def to_as
|
248
|
+
"%r11"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class OpR12<OpReg64
|
253
|
+
def reg_no
|
254
|
+
12
|
255
|
+
end
|
256
|
+
|
257
|
+
def to_as
|
258
|
+
"%r12"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
class OpR13<OpReg64
|
263
|
+
def reg_no
|
264
|
+
13
|
265
|
+
end
|
266
|
+
|
267
|
+
def to_as
|
268
|
+
"%r13"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
class OpR14<OpReg64
|
273
|
+
def reg_no
|
274
|
+
14
|
275
|
+
end
|
276
|
+
|
277
|
+
def to_as
|
278
|
+
"%r14"
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
class OpR15<OpReg64
|
283
|
+
def reg_no
|
284
|
+
15
|
285
|
+
end
|
286
|
+
|
287
|
+
def to_as
|
288
|
+
"%r15"
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
class OpRegXMM<OpRegistor
|
293
|
+
end
|
294
|
+
|
295
|
+
class OpRXMM0<OpRegXMM
|
296
|
+
def reg_no
|
297
|
+
0
|
298
|
+
end
|
299
|
+
|
300
|
+
def to_as
|
301
|
+
"%xmm0"
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
class OpRXMM1<OpRegXMM
|
306
|
+
def reg_no
|
307
|
+
1
|
308
|
+
end
|
309
|
+
|
310
|
+
def to_as
|
311
|
+
"%xmm1"
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
class OpRXMM2<OpRegXMM
|
316
|
+
def reg_no
|
317
|
+
2
|
318
|
+
end
|
319
|
+
|
320
|
+
def to_as
|
321
|
+
"%xmm2"
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
class OpRXMM3<OpRegXMM
|
326
|
+
def reg_no
|
327
|
+
3
|
328
|
+
end
|
329
|
+
|
330
|
+
def to_as
|
331
|
+
"%xmm3"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
class OpRXMM4<OpRegXMM
|
336
|
+
def reg_no
|
337
|
+
4
|
338
|
+
end
|
339
|
+
|
340
|
+
def to_as
|
341
|
+
"%xmm4"
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
class OpRXMM5<OpRegXMM
|
346
|
+
def reg_no
|
347
|
+
5
|
348
|
+
end
|
349
|
+
|
350
|
+
def to_as
|
351
|
+
"%xmm5"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
class OpRXMM6<OpRegXMM
|
356
|
+
def reg_no
|
357
|
+
6
|
358
|
+
end
|
359
|
+
|
360
|
+
def to_as
|
361
|
+
"%xmm6"
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
class OpRXMM7<OpRegXMM
|
366
|
+
def reg_no
|
367
|
+
7
|
368
|
+
end
|
369
|
+
|
370
|
+
def to_as
|
371
|
+
"%xmm7"
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
class OpRXMM8<OpRegXMM
|
376
|
+
def reg_no
|
377
|
+
8
|
378
|
+
end
|
379
|
+
|
380
|
+
def to_as
|
381
|
+
"%xmm8"
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
class OpRXMM9<OpRegXMM
|
386
|
+
def reg_no
|
387
|
+
9
|
388
|
+
end
|
389
|
+
|
390
|
+
def to_as
|
391
|
+
"%xmm9"
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
class OpRXMM10<OpRegXMM
|
396
|
+
def reg_no
|
397
|
+
10
|
398
|
+
end
|
399
|
+
|
400
|
+
def to_as
|
401
|
+
"%xmm10"
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
class OpRXMM11<OpRegXMM
|
406
|
+
def reg_no
|
407
|
+
11
|
408
|
+
end
|
409
|
+
|
410
|
+
def to_as
|
411
|
+
"%xmm11"
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
class OpRXMM12<OpRegXMM
|
416
|
+
def reg_no
|
417
|
+
12
|
418
|
+
end
|
419
|
+
|
420
|
+
def to_as
|
421
|
+
"%xmm12"
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
class OpRXMM13<OpRegXMM
|
426
|
+
def reg_no
|
427
|
+
13
|
428
|
+
end
|
429
|
+
|
430
|
+
def to_as
|
431
|
+
"%xmm13"
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
class OpRXMM14<OpRegXMM
|
436
|
+
def reg_no
|
437
|
+
14
|
438
|
+
end
|
439
|
+
|
440
|
+
def to_as
|
441
|
+
"%xmm14"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
class OpRXMM15<OpRegXMM
|
446
|
+
def reg_no
|
447
|
+
15
|
448
|
+
end
|
449
|
+
|
450
|
+
def to_as
|
451
|
+
"%xmm15"
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
module AssemblerUtilIAModrm
|
456
|
+
def small_integer_8bit?(num)
|
457
|
+
num = (num & 0x7fff_ffff) - (num & 0x8000_0000)
|
458
|
+
num.abs < 0x7f
|
459
|
+
end
|
460
|
+
|
461
|
+
def small_integer_32bit?(num)
|
462
|
+
num = (num & 0x7fff_ffff_ffff_ffff) - (num & 0x8000_0000_0000_0000)
|
463
|
+
num.abs < 0x7fff_ffff
|
464
|
+
end
|
465
|
+
|
466
|
+
def modrm_indirect_off32(regv, rm_reg, rm_disp)
|
467
|
+
fstb = 0b10000000 | ((regv & 7) << 3) | (rm_reg.reg_no & 7)
|
468
|
+
if rm_reg.is_a?(OpESP) or rm_reg.is_a?(OpRSP) then
|
469
|
+
[[fstb, 0b00100100, rm_disp], "C2L"]
|
470
|
+
else
|
471
|
+
[[fstb, rm_disp], "CL"]
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
def modrm_indirect_off8(regv, rm_reg, rm_disp)
|
476
|
+
fstb = 0b01000000 | ((regv & 7) << 3) | (rm_reg.reg_no & 7)
|
477
|
+
if rm_reg.is_a?(OpESP) or rm_reg.is_a?(OpRSP) then
|
478
|
+
[[fstb, 0b00100100, rm_disp], "C3"]
|
479
|
+
else
|
480
|
+
[[fstb, rm_disp], "CC"]
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
def modrm_indirect(reg, rm)
|
485
|
+
regv = nil
|
486
|
+
case reg
|
487
|
+
when Integer
|
488
|
+
regv = reg
|
489
|
+
|
490
|
+
else
|
491
|
+
regv = reg.value
|
492
|
+
end
|
493
|
+
|
494
|
+
case rm.disp
|
495
|
+
when 0
|
496
|
+
if rm.reg.is_a?(OpEBP) or rm.reg.is_a?(OpRBP) then
|
497
|
+
modrm_indirect_off8(regv, rm.reg, 0)
|
498
|
+
else
|
499
|
+
fstb = 0b00000000 | ((regv & 7) << 3) | (rm.reg.reg_no & 7)
|
500
|
+
if rm.reg.is_a?(OpESP) or rm.reg.is_a?(OpRSP) then
|
501
|
+
[[fstb, 0x24], "C2"]
|
502
|
+
else
|
503
|
+
[[fstb], "C"]
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
when OpImmidiate8
|
508
|
+
modrm_indirect_off8(regv, rm.reg, rm.disp.value)
|
509
|
+
|
510
|
+
when OpImmidiate32
|
511
|
+
modrm_indirect_off32(regv, rm.reg, rm.disp.value)
|
512
|
+
|
513
|
+
when Integer
|
514
|
+
if small_integer_8bit?(rm.disp.abs) then
|
515
|
+
modrm_indirect_off8(regv, rm.reg, rm.disp)
|
516
|
+
else
|
517
|
+
modrm_indirect_off32(regv, rm.reg, rm.disp)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
def modrm(inst, reg, rm, dst, src, src2 = nil)
|
523
|
+
case reg
|
524
|
+
when Integer
|
525
|
+
case rm
|
526
|
+
when OpRegistor
|
527
|
+
[[0b11000000 | ((reg & 7) << 3) | (rm.reg_no & 7)], "C"]
|
528
|
+
|
529
|
+
when OpIndirect
|
530
|
+
modrm_indirect(reg, rm)
|
531
|
+
|
532
|
+
when Integer, OpImmidiate
|
533
|
+
[[0b00000000 | ((reg & 7) << 3) | 5], "C"]
|
534
|
+
|
535
|
+
else
|
536
|
+
return nosupported_addressing_mode(inst, dst, src, src2)
|
537
|
+
end
|
538
|
+
|
539
|
+
when OpRegistor
|
540
|
+
case rm
|
541
|
+
when OpRegistor
|
542
|
+
[[0b11000000 | ((reg.reg_no & 7) << 3) | (rm.reg_no & 7)], "C"]
|
543
|
+
|
544
|
+
when OpIndirect
|
545
|
+
modrm_indirect(reg, rm)
|
546
|
+
end
|
547
|
+
|
548
|
+
else
|
549
|
+
return nosupported_addressing_mode(inst, dst, src, src2)
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
module AssemblerUtilIA
|
555
|
+
include AssemblerUtilIAModrm
|
556
|
+
|
557
|
+
def nosupported_addressing_mode(inst, dst, src, src2 = nil)
|
558
|
+
mess = "Not supported addessing mode in #{inst} #{dst} #{src} #{src2}"
|
559
|
+
raise IlligalOperand, mess
|
560
|
+
end
|
561
|
+
|
562
|
+
def common_operand_80_imm8(dst, src, optc, inst)
|
563
|
+
rexseq, rexfmt = rex(dst, src)
|
564
|
+
modseq, modfmt = modrm(inst, optc, dst, dst, src)
|
565
|
+
fmt = "#{rexfmt}C#{modfmt}C"
|
566
|
+
(rexseq + [0x83] + modseq + [src]).pack(fmt)
|
567
|
+
end
|
568
|
+
|
569
|
+
def common_operand_80(dst, src, bopc, optc, inst)
|
570
|
+
case dst
|
571
|
+
when OpReg8
|
572
|
+
case src
|
573
|
+
when OpImmidiate8, Integer
|
574
|
+
if dst.class == OpAL then
|
575
|
+
[bopc + 0x4, src.value].pack("C2")
|
576
|
+
else
|
577
|
+
modseq, modfmt = modrm(inst, optc, dst, dst, src)
|
578
|
+
([0x80] + modseq + [src.value]).pack("C#{modfmt}C")
|
579
|
+
end
|
580
|
+
|
581
|
+
when OpReg8
|
582
|
+
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
583
|
+
([bopc] + modseq).pack("C#{modfmt}")
|
584
|
+
|
585
|
+
else
|
586
|
+
return nosupported_addressing_mode(inst, dst, src)
|
587
|
+
end
|
588
|
+
|
589
|
+
when OpReg32, OpReg64
|
590
|
+
case src
|
591
|
+
when OpImmidiate8
|
592
|
+
common_operand_80_imm8(dst, src.value, optc, inst)
|
593
|
+
|
594
|
+
when OpImmidiate32, Integer
|
595
|
+
srcv = nil
|
596
|
+
if src.is_a?(Integer)
|
597
|
+
srcv = src
|
598
|
+
else
|
599
|
+
srcv = src.value
|
600
|
+
end
|
601
|
+
|
602
|
+
if small_integer_8bit?(srcv) then
|
603
|
+
return common_operand_80_imm8(dst, srcv, optc, inst)
|
604
|
+
end
|
605
|
+
|
606
|
+
rexseq, rexfmt = rex(dst, src)
|
607
|
+
|
608
|
+
if dst.class == OpEAX or dst.class == OpRAX then
|
609
|
+
[*rexseq, bopc + 0x5, srcv].pack("#{rexfmt}CL")
|
610
|
+
else
|
611
|
+
modseq, modfmt = modrm(inst, optc, dst, dst, src)
|
612
|
+
(rexseq + [0x81] + modseq + [srcv]).pack("#{rexfmt}C#{modfmt}L")
|
613
|
+
end
|
614
|
+
|
615
|
+
when OpImmidiate64
|
616
|
+
srcv = src.value
|
617
|
+
|
618
|
+
if small_integer_8bit?(srcv) then
|
619
|
+
return common_operand_80_imm8(dst, srcv, optc, inst)
|
620
|
+
end
|
621
|
+
|
622
|
+
rexseq, rexfmt = rex(dst, src)
|
623
|
+
|
624
|
+
if dst.class == OpEAX or dst.class == OpRAX then
|
625
|
+
[*rexseq, bopc + 0x5, srcv].pack("#{rexfmt}CQ")
|
626
|
+
else
|
627
|
+
modseq, modfmt = modrm(inst, optc, dst, dst, src)
|
628
|
+
(rexseq + [0x81] + modseq + [srcv]).pack("#{rexfmt}C#{modfmt}Q")
|
629
|
+
end
|
630
|
+
|
631
|
+
when OpReg32, OpReg64
|
632
|
+
rexseq, rexfmt = rex(dst, src)
|
633
|
+
modseq, modfmt = modrm(inst, src, dst, dst, src)
|
634
|
+
(rexseq + [bopc + 0x01] + modseq).pack("#{rexfmt}C#{modfmt}")
|
635
|
+
|
636
|
+
when OpMem32, OpMem64
|
637
|
+
rexseq, rexfmt = rex(dst, src)
|
638
|
+
modseq, modfmt = modrm(inst, src, dst, dst, src)
|
639
|
+
(rexseq + [bopc + 0x03] + modseq).pack("#{rexfmt}C#{modfmt}")
|
640
|
+
|
641
|
+
when OpIndirect
|
642
|
+
rexseq, rexfmt = rex(src, dst)
|
643
|
+
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
644
|
+
(rexseq + [bopc + 0x03] + modseq).pack("#{rexfmt}C#{modfmt}")
|
645
|
+
|
646
|
+
else
|
647
|
+
return nosupported_addressing_mode(inst, dst, src)
|
648
|
+
end
|
649
|
+
|
650
|
+
when OpIndirect
|
651
|
+
case src
|
652
|
+
when OpImmidiate8
|
653
|
+
rexseq, rexfmt = rex(dst, src)
|
654
|
+
modseq, modfmt = modrm(inst, optc, src, dst, src)
|
655
|
+
(rexseq + [0x83] + modseq + [src.value]).pack("#{rexfmt}C#{modfmt}")
|
656
|
+
|
657
|
+
when OpImmidiate32, Integer
|
658
|
+
rexseq, rexfmt = rex(dst, src)
|
659
|
+
modseq, modfmt = modrm(inst, optc, src, dst, src)
|
660
|
+
(rexseq + [0x81] + modseq + [src.value]).pack("#{rexfmt}C#{modfmt}L")
|
661
|
+
|
662
|
+
when OpReg32, OpReg64
|
663
|
+
rexseq, rexfmt = rex(dst, src)
|
664
|
+
modseq, modfmt = modrm(inst, src, dst, dst, src)
|
665
|
+
(rexseq + [bopc + 0x1] + modseq).pack("#{rexfmt}C#{modfmt}")
|
666
|
+
|
667
|
+
else
|
668
|
+
return nosupported_addressing_mode(inst, dst, src)
|
669
|
+
end
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
def common_jcc(addr, opc, lopc, inst)
|
674
|
+
addr2 = addr
|
675
|
+
if addr.is_a?(OpMemory) then
|
676
|
+
addr2 = addr.value
|
677
|
+
end
|
678
|
+
offset = addr2 - @asm.current_address - 2
|
679
|
+
if offset > -128 and offset < 127 and false then
|
680
|
+
[opc, offset].pack("C2")
|
681
|
+
else
|
682
|
+
offset = addr2 - @asm.current_address - 6
|
683
|
+
[0x0F, lopc, offset].pack("C2L")
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
def common_setcc(dst, opc, inst)
|
688
|
+
case dst
|
689
|
+
when OpReg8, OpIndirect, OpMem8
|
690
|
+
modseq, modfmt = modrm(inst, 0, dst, dst, nil)
|
691
|
+
([0x0F, opc] + modseq).pack("C2#{modfmt}")
|
692
|
+
else
|
693
|
+
return nosupported_addressing_mode(inst, dst, nil)
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
def common_shift(dst, optc, shftnum, inst)
|
698
|
+
rexseq, rexfmt = rex(dst, nil)
|
699
|
+
modseq, modfmt = modrm(inst, optc, dst, dst, shftnum)
|
700
|
+
if shftnum.is_a?(OpImmidiate8) then
|
701
|
+
shftnum = shftnum.value
|
702
|
+
end
|
703
|
+
|
704
|
+
if shftnum == 1 then
|
705
|
+
(rexseq + [0xD1] + modseq ).pack("#{rexfmt}C#{modfmt}")
|
706
|
+
else
|
707
|
+
(rexseq + [0xC1] + modseq + [shftnum]).pack("#{rexfmt}C#{modfmt}C")
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
def common_movssd(dst, src, op, inst)
|
712
|
+
case dst
|
713
|
+
when OpRegXMM
|
714
|
+
case src
|
715
|
+
when OpRegXMM
|
716
|
+
rexseq, rexfmt = rex(dst, src)
|
717
|
+
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
718
|
+
(rexseq + [op, 0x0F, 0x10] + modseq).pack("#{rexfmt}C3#{modfmt}")
|
719
|
+
|
720
|
+
when OpIndirect
|
721
|
+
rexseq, rexfmt = rex(dst, src)
|
722
|
+
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
723
|
+
(rexseq + [op, 0x0F, 0x10] + modseq).pack("#{rexfmt}C3#{modfmt}")
|
724
|
+
|
725
|
+
else
|
726
|
+
return nosupported_addressing_mode(inst, dst, src)
|
727
|
+
end
|
728
|
+
|
729
|
+
when OpIndirect
|
730
|
+
case src
|
731
|
+
when OpRegXMM
|
732
|
+
rexseq, rexfmt = rex(dst, src)
|
733
|
+
modseq, modfmt = modrm(inst, src, dst, dst, src)
|
734
|
+
(rexseq + [op, 0x0F, 0x11] + modseq).pack("#{rexfmt}C3#{modfmt}")
|
735
|
+
|
736
|
+
else
|
737
|
+
return nosupported_addressing_mode(inst, dst, src)
|
738
|
+
end
|
739
|
+
|
740
|
+
else
|
741
|
+
return nosupported_addressing_mode(inst, dst, src)
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
def common_arithxmm(dst, src, op0, op1, inst)
|
746
|
+
case dst
|
747
|
+
when OpRegXMM
|
748
|
+
case src
|
749
|
+
when OpRegXMM
|
750
|
+
rexseq, rexfmt = rex(dst, src)
|
751
|
+
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
752
|
+
(rexseq + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
|
753
|
+
|
754
|
+
when OpIndirect
|
755
|
+
rexseq, rexfmt = rex(dst, src)
|
756
|
+
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
757
|
+
(rexseq + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
|
758
|
+
|
759
|
+
else
|
760
|
+
return nosupported_addressing_mode(inst, dst, src)
|
761
|
+
end
|
762
|
+
|
763
|
+
else
|
764
|
+
return nosupported_addressing_mode(inst, dst, src)
|
765
|
+
end
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
class GeneratorIABinary<Generator
|
770
|
+
case $ruby_platform
|
771
|
+
when /x86_64/
|
772
|
+
include AssemblerUtilX64
|
773
|
+
when /i.86/
|
774
|
+
include AssemblerUtilX86
|
775
|
+
end
|
776
|
+
include AssemblerUtilIA
|
777
|
+
|
778
|
+
def initialize(asm, handler = "ytl_step_handler")
|
779
|
+
super(asm)
|
780
|
+
@step_handler = YTLJit.address_of(handler)
|
781
|
+
end
|
782
|
+
|
783
|
+
def call_stephandler
|
784
|
+
if @asm.step_mode
|
785
|
+
call(@step_handler)
|
786
|
+
else
|
787
|
+
""
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
791
|
+
def add(dst, src)
|
792
|
+
common_operand_80(dst, src, 0x00, 0x0, :add)
|
793
|
+
end
|
794
|
+
|
795
|
+
def or(dst, src)
|
796
|
+
common_operand_80(dst, src, 0x08, 0x1, :or)
|
797
|
+
end
|
798
|
+
|
799
|
+
def adc(dst, src)
|
800
|
+
common_operand_80(dst, src, 0x10, 0x2, :adc)
|
801
|
+
end
|
802
|
+
|
803
|
+
def sbb(dst, src)
|
804
|
+
common_operand_80(dst, src, 0x18, 0x3, :sbb)
|
805
|
+
end
|
806
|
+
|
807
|
+
def and(dst, src)
|
808
|
+
common_operand_80(dst, src, 0x20, 0x4, :and)
|
809
|
+
end
|
810
|
+
|
811
|
+
def sub(dst, src)
|
812
|
+
common_operand_80(dst, src, 0x28, 0x5, :sub)
|
813
|
+
end
|
814
|
+
|
815
|
+
def xor(dst, src)
|
816
|
+
common_operand_80(dst, src, 0x30, 0x6, :xor)
|
817
|
+
end
|
818
|
+
|
819
|
+
def cmp(dst, src)
|
820
|
+
common_operand_80(dst, src, 0x38, 0x7, :cmp)
|
821
|
+
end
|
822
|
+
|
823
|
+
def mov(dst, src)
|
824
|
+
case dst
|
825
|
+
when OpReg8
|
826
|
+
case src
|
827
|
+
when OpImmidiate8
|
828
|
+
[0xB0 + (dst.reg_no & 7), src.value].pack("C2")
|
829
|
+
|
830
|
+
when Integer
|
831
|
+
[0xB0 + (dst.reg_no & 7), src].pack("C2")
|
832
|
+
|
833
|
+
when OpReg8
|
834
|
+
modseq, modfmt = modrm(:mov, dst, src, dst, src)
|
835
|
+
([0x88] + modseq).pack("C#{modfmt}")
|
836
|
+
|
837
|
+
when OpIndirect
|
838
|
+
modseq, modfmt = modrm(:mov, dst, src, dst, src)
|
839
|
+
([0x8A] + modseq).pack("C#{modfmt}")
|
840
|
+
|
841
|
+
else
|
842
|
+
return nosupported_addressing_mode(:mov, dst, src)
|
843
|
+
end
|
844
|
+
|
845
|
+
when OpReg32
|
846
|
+
case src
|
847
|
+
when OpImmidiate32
|
848
|
+
[0xB8 + (dst.reg_no & 7), src.value].pack("CL")
|
849
|
+
|
850
|
+
when Integer
|
851
|
+
[0xB8 + (dst.reg_no & 7), src].pack("CL")
|
852
|
+
|
853
|
+
when OpReg32, OpReg64
|
854
|
+
rexseq, rexfmt = rex(dst, src)
|
855
|
+
modseq, modfmt = modrm(:mov, src, dst, dst, src)
|
856
|
+
(rexseq + [0x89] + modseq).pack("#{rexfmt}C#{modfmt}")
|
857
|
+
|
858
|
+
when OpIndirect
|
859
|
+
rexseq, rexfmt = rex(dst, src)
|
860
|
+
modseq, modfmt = modrm(:mov, dst, src, dst, src)
|
861
|
+
(rexseq + [0x8B] + modseq).pack("#{rexfmt}C#{modfmt}")
|
862
|
+
|
863
|
+
else
|
864
|
+
return nosupported_addressing_mode(:mov, dst, src)
|
865
|
+
end
|
866
|
+
|
867
|
+
when OpReg64
|
868
|
+
case src
|
869
|
+
when OpImmidiate32
|
870
|
+
rexseq, rexfmt = rex(dst, src)
|
871
|
+
modseq, modfmt = modrm(:mov, 0, dst, dst, src)
|
872
|
+
(rexseq + [0xC7] + modseq + [src.value]).pack("#{rexfmt}C#{modfmt}L")
|
873
|
+
|
874
|
+
when Integer
|
875
|
+
rexseq, rexfmt = rex(dst, src)
|
876
|
+
if small_integer_32bit?(src) then
|
877
|
+
modseq, modfmt = modrm(:mov, 0, dst, dst, src)
|
878
|
+
(rexseq + [0xC7] + modseq + [src]).pack("#{rexfmt}C#{modfmt}L")
|
879
|
+
else
|
880
|
+
[*rexseq, 0xB8 + (dst.reg_no & 7), src].pack("#{rexfmt}CQ")
|
881
|
+
end
|
882
|
+
|
883
|
+
when OpImmidiate64
|
884
|
+
rexseq, rexfmt = rex(dst, src)
|
885
|
+
[*rexseq, 0xB8 + (dst.reg_no & 7), src.value].pack("#{rexfmt}CQ")
|
886
|
+
|
887
|
+
when OpReg32, OpReg64
|
888
|
+
rexseq, rexfmt = rex(dst, src)
|
889
|
+
modseq, modfmt = modrm(:mov, src, dst, dst, src)
|
890
|
+
(rexseq + [0x89] + modseq).pack("#{rexfmt}C#{modfmt}")
|
891
|
+
|
892
|
+
when OpIndirect
|
893
|
+
rexseq, rexfmt = rex(src, dst)
|
894
|
+
modseq, modfmt = modrm(:mov, dst, src, dst, src)
|
895
|
+
(rexseq + [0x8B] + modseq).pack("#{rexfmt}C#{modfmt}")
|
896
|
+
|
897
|
+
else
|
898
|
+
return nosupported_addressing_mode(:mov, dst, src)
|
899
|
+
end
|
900
|
+
|
901
|
+
when OpIndirect
|
902
|
+
case src
|
903
|
+
when OpReg8
|
904
|
+
rexseq, rexfmt = rex(dst, src)
|
905
|
+
modseq, modfmt = modrm(:mov, src, dst, dst, src)
|
906
|
+
(rexseq + [0x88] + modseq).pack("#{rexfmt}C#{modfmt}")
|
907
|
+
|
908
|
+
when OpReg32, OpReg64
|
909
|
+
rexseq, rexfmt = rex(dst, src)
|
910
|
+
modseq, modfmt = modrm(:mov, src, dst, dst, src)
|
911
|
+
(rexseq + [0x89] + modseq).pack("#{rexfmt}C#{modfmt}")
|
912
|
+
|
913
|
+
when OpImmidiate8
|
914
|
+
rexseq, rexfmt = rex(dst, 0)
|
915
|
+
modseq, modfmt = modrm(:mov, 0, dst, dst, src)
|
916
|
+
(rexseq + [0xC6] + modseq + [src.value]).pack("#{rexfmt}C#{modfmt}C")
|
917
|
+
|
918
|
+
when OpImmidiate32
|
919
|
+
rexseq, rexfmt = rex(dst, 0)
|
920
|
+
modseq, modfmt = modrm(:mov, 0, dst, dst, src)
|
921
|
+
(rexseq + [0xC7] + modseq + [src.value]).pack("#{rexfmt}C#{modfmt}L")
|
922
|
+
|
923
|
+
when Integer
|
924
|
+
rexseq, rexfmt = rex(dst, 0)
|
925
|
+
modseq, modfmt = modrm(:mov, 0, dst, dst, src)
|
926
|
+
(rexseq + [0xC7] + modseq + [src]).pack("#{rexfmt}C#{modfmt}L")
|
927
|
+
|
928
|
+
else
|
929
|
+
return nosupported_addressing_mode(:mov, dst, src)
|
930
|
+
end
|
931
|
+
|
932
|
+
else
|
933
|
+
return nosupported_addressing_mode(:mov, dst, src)
|
934
|
+
end
|
935
|
+
end
|
936
|
+
|
937
|
+
def lea(dst, src)
|
938
|
+
unless dst.is_a?(OpReg32) or dst.is_a?(OpReg64)
|
939
|
+
return nosupported_addressing_mode(:lea, dst, src)
|
940
|
+
end
|
941
|
+
|
942
|
+
if !src.is_a?(OpIndirect)
|
943
|
+
return nosupported_addressing_mode(:lea, dst, src)
|
944
|
+
end
|
945
|
+
|
946
|
+
rexseq, rexfmt = rex(src, dst)
|
947
|
+
modseq, modfmt = modrm(:lea, dst, src, dst, src)
|
948
|
+
(rexseq + [0x8D] + modseq).pack("#{rexfmt}C#{modfmt}")
|
949
|
+
end
|
950
|
+
|
951
|
+
def push(dst)
|
952
|
+
rexseq, rexfmt = rex(dst, nil)
|
953
|
+
case dst
|
954
|
+
when OpReg32, OpReg64
|
955
|
+
[*rexseq, 0x50 + (dst.reg_no & 7)].pack("#{rexfmt}C")
|
956
|
+
|
957
|
+
when OpIndirect
|
958
|
+
modseq, modfmt = modrm(:push, 6, dst, dst, nil)
|
959
|
+
(rexseq + [0xFF] + modseq).pack("#{rexfmt}C#{modfmt}")
|
960
|
+
|
961
|
+
else
|
962
|
+
return nosupported_addressing_mode(:push, dst, nil)
|
963
|
+
end
|
964
|
+
end
|
965
|
+
|
966
|
+
def pop(dst)
|
967
|
+
rexseq, rexfmt = rex(dst, nil)
|
968
|
+
case dst
|
969
|
+
when OpReg32, OpReg64
|
970
|
+
[*rexseq, 0x58 + (dst.reg_no & 7)].pack("#{rexfmt}C")
|
971
|
+
|
972
|
+
when OpIndirect
|
973
|
+
modseq, modfmt = modrm(:pop, 0, dst, dst, nil)
|
974
|
+
([0x8F] + modseq).pack("C#{modfmt}")
|
975
|
+
|
976
|
+
else
|
977
|
+
return nosupported_addressing_mode(:pop, dst, nil)
|
978
|
+
end
|
979
|
+
end
|
980
|
+
|
981
|
+
def ja(addr)
|
982
|
+
common_jcc(addr, 0x77, 0x87, :ja)
|
983
|
+
end
|
984
|
+
|
985
|
+
def jae(addr)
|
986
|
+
common_jcc(addr, 0x73, 0x83, :jae)
|
987
|
+
end
|
988
|
+
|
989
|
+
def jb(addr)
|
990
|
+
common_jcc(addr, 0x72, 0x82, :jb)
|
991
|
+
end
|
992
|
+
|
993
|
+
def jbe(addr)
|
994
|
+
common_jcc(addr, 0x76, 0x86, :jbe)
|
995
|
+
end
|
996
|
+
|
997
|
+
def jl(addr)
|
998
|
+
common_jcc(addr, 0x7c, 0x8c, :jl)
|
999
|
+
end
|
1000
|
+
|
1001
|
+
def jle(addr)
|
1002
|
+
common_jcc(addr, 0x7e, 0x8e, :jle)
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def jna(addr)
|
1006
|
+
common_jcc(addr, 0x76, 0x86, :jna)
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
def jnae(addr)
|
1010
|
+
common_jcc(addr, 0x72, 0x82, :jnae)
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
def jnb(addr)
|
1014
|
+
common_jcc(addr, 0x73, 0x83, :jnb)
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
def jnbe(addr)
|
1018
|
+
common_jcc(addr, 0x77, 0x87, :jnbe)
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
def jnc(addr)
|
1022
|
+
common_jcc(addr, 0x73, 0x83, :jnc)
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
def jnle(addr)
|
1026
|
+
common_jcc(addr, 0x7f, 0x8f, :jnle)
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
def jno(addr)
|
1030
|
+
common_jcc(addr, 0x71, 0x81, :jno)
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
def jo(addr)
|
1034
|
+
common_jcc(addr, 0x70, 0x80, :jo)
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def jz(addr)
|
1038
|
+
common_jcc(addr, 0x74, 0x84, :jz)
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
def jnz(addr)
|
1042
|
+
common_jcc(addr, 0x75, 0x85, :jnz)
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
def seta(dst)
|
1046
|
+
common_setcc(dst, 0x97, :seta)
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
def setae(dst)
|
1050
|
+
common_setcc(dst, 0x93, :setae)
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
def setb(dst)
|
1054
|
+
common_setcc(dst, 0x92, :setb)
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
def setbe(dst)
|
1058
|
+
common_setcc(dst, 0x96, :setbe)
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
def setg(dst)
|
1062
|
+
common_setcc(dst, 0x9f, :setg)
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
def setge(dst)
|
1066
|
+
common_setcc(dst, 0x9d, :setge)
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
def setl(dst)
|
1070
|
+
common_setcc(dst, 0x9c, :setl)
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def setle(dst)
|
1074
|
+
common_setcc(dst, 0x9e, :setle)
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
def setna(dst)
|
1078
|
+
common_setcc(dst, 0x96, :setna)
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
def setnae(dst)
|
1082
|
+
common_setcc(dst, 0x92, :setnae)
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
def setnb(dst)
|
1086
|
+
common_setcc(dst, 0x93, :setnb)
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
def setnbe(dst)
|
1090
|
+
common_setcc(dst, 0x97, :setnbe)
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
def setnc(dst)
|
1094
|
+
common_setcc(dst, 0x93, :setnc)
|
1095
|
+
end
|
1096
|
+
|
1097
|
+
def setnle(dst)
|
1098
|
+
common_setcc(dst, 0x9f, :setnle)
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
def setno(dst)
|
1102
|
+
common_setcc(dst, 0x91, :setno)
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
def seto(dst)
|
1106
|
+
common_setcc(dst, 0x90, :seto)
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def setz(dst)
|
1110
|
+
common_setcc(dst, 0x94, :setz)
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
def setnz(dst)
|
1114
|
+
common_setcc(dst, 0x95, :setnz)
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
def jmp(addr)
|
1118
|
+
addr2 = addr
|
1119
|
+
if addr.is_a?(OpMemory) then
|
1120
|
+
addr2 = addr.value
|
1121
|
+
end
|
1122
|
+
case addr2
|
1123
|
+
when Integer
|
1124
|
+
offset = addr2 - @asm.current_address - 2
|
1125
|
+
if offset > -128 and offset < 127 then
|
1126
|
+
[0xeb, offset].pack("C2")
|
1127
|
+
else
|
1128
|
+
offset = addr2 - @asm.current_address - 5
|
1129
|
+
[0xe9, offset].pack("CL")
|
1130
|
+
end
|
1131
|
+
else
|
1132
|
+
modseq, modfmt = modrm(:jmp, 4, addr2, addr2, nil)
|
1133
|
+
([0xff] + modseq).pack("C#{modfmt}")
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
def call(addr)
|
1138
|
+
offset = 0
|
1139
|
+
case addr
|
1140
|
+
when Integer
|
1141
|
+
offset = addr - @asm.current_address - 5
|
1142
|
+
immidiate_call(addr, offset)
|
1143
|
+
|
1144
|
+
when OpMemory
|
1145
|
+
offset = addr.value - @asm.current_address - 5
|
1146
|
+
immidiate_call(addr, offset)
|
1147
|
+
|
1148
|
+
else
|
1149
|
+
rexseq, rexfmt = rex(addr, nil)
|
1150
|
+
modseq, modfmt = modrm(:call, 2, addr, nil, addr)
|
1151
|
+
(rexseq + [0xff] + modseq).pack("#{rexfmt}C#{modfmt}")
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
def ret
|
1156
|
+
[0xc3].pack("C")
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
def sal(dst, shftnum = 1)
|
1160
|
+
common_shift(dst, 4, shftnum, :sal)
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
def sar(dst, shftnum = 1)
|
1164
|
+
common_shift(dst, 7, shftnum, :sar)
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
def shl(dst, shftnum = 1)
|
1168
|
+
common_shift(dst, 4, shftnum, :shl)
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
def shr(dst, shftnum = 1)
|
1172
|
+
common_shift(dst, 5, shftnum, :shr)
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
def rcl(dst, shftnum = 1)
|
1176
|
+
common_shift(dst, 2, shftnum, :rcl)
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
def rcr(dst, shftnum = 1)
|
1180
|
+
common_shift(dst, 3, shftnum, :rcr)
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def rol(dst, shftnum = 1)
|
1184
|
+
common_shift(dst, 0, shftnum, :rol)
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
def ror(dst, shftnum = 1)
|
1188
|
+
common_shift(dst, 1, shftnum, :ror)
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
def imul(dst, src = nil, src2 = nil)
|
1192
|
+
rexseq, rexfmt = rex(dst, src)
|
1193
|
+
case dst
|
1194
|
+
when OpReg8, OpMem8
|
1195
|
+
if src == nil then
|
1196
|
+
modseq, modfmt = modrm(:imul, 5, dst, dst, 5)
|
1197
|
+
return ([0xF6] + modseq).pack("C#{modfmt}")
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
when OpIndirect, OpMem32
|
1201
|
+
if src != nil then
|
1202
|
+
modseq, modfmt = modrm(:imul, 5, dst, dst, 5)
|
1203
|
+
return (rexseq + [0xF7] + modseq).pack("#{rexfmt}C#(modfmt}")
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
when OpReg32, OpReg64
|
1207
|
+
case src
|
1208
|
+
when nil
|
1209
|
+
modseq, modfmt = modrm(:imul, 5, dst, dst, 5)
|
1210
|
+
return (rexseq + [0xF7] + modseq).pack("#{rexfmt}C#(modfmt}")
|
1211
|
+
|
1212
|
+
when OpReg32, OpMem32, OpIndirect, OpReg64
|
1213
|
+
modseq, modfmt = modrm(:imul, dst, src, dst, src, src2)
|
1214
|
+
case src2
|
1215
|
+
when nil
|
1216
|
+
return (rexseq + [0x0F, 0xAF] + modseq).pack("#{rexfmt}C2#{modfmt}")
|
1217
|
+
|
1218
|
+
when OpImmidiate8
|
1219
|
+
fmt = "#{rexfmt}C#{modfmt}C"
|
1220
|
+
return (rexseq + [0x6B] + modseq + [src2.value]).pack(fmt)
|
1221
|
+
|
1222
|
+
when OpImmidiate32
|
1223
|
+
fmt = "#{rexfmt}C#{modfmt}L"
|
1224
|
+
return (rexseq + [0x69] + modseq + [src2.value]).pack(fmt)
|
1225
|
+
|
1226
|
+
when Integer
|
1227
|
+
fmt = "#{rexfmt}C#{modfmt}L"
|
1228
|
+
return (rexseq + [0x69] + modseq + [src2]).pack(fmt)
|
1229
|
+
end
|
1230
|
+
|
1231
|
+
when OpImmidiate8
|
1232
|
+
modseq, modfmt = modrm(:imul, dst, dst, dst, src)
|
1233
|
+
fmt = "#{rexfmt}C#{modfmt}C"
|
1234
|
+
return (rexseq + [0x6B] + modseq + [src.value]).pack(fmt)
|
1235
|
+
|
1236
|
+
|
1237
|
+
when OpImmidiate32
|
1238
|
+
modseq, modfmt = modrm(:imul, dst, dst, dst, src)
|
1239
|
+
fmt = "#{rexfmt}C#{modfmt}L"
|
1240
|
+
return (rexseq + [0x69] + modseq + [src.value]).pack(fmt)
|
1241
|
+
|
1242
|
+
when Integer
|
1243
|
+
modseq, modfmt = modrm(:imul, dst, dst, dst, src)
|
1244
|
+
fmt = "#{rexfmt}C#{modfmt}L"
|
1245
|
+
return (rexseq + [0x69] + modseq + [src]).pack(fmt)
|
1246
|
+
|
1247
|
+
end
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
return nosupported_addressing_mode(:imul, dst, src, src2)
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
def movss(dst, src)
|
1254
|
+
common_movssd(dst, src, 0xF3, :movss)
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
def movsd(dst, src)
|
1258
|
+
common_movssd(dst, src, 0xF2, :movsd)
|
1259
|
+
end
|
1260
|
+
|
1261
|
+
def addss(dst, src)
|
1262
|
+
common_arithxmm(dst, src, 0xF3, 0x58, :addss)
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
def addsd(dst, src)
|
1266
|
+
common_arithxmm(dst, src, 0xF2, 0x58, :addsd)
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
def subss(dst, src)
|
1270
|
+
common_arithxmm(dst, src, 0xF3, 0x5C, :subss)
|
1271
|
+
end
|
1272
|
+
|
1273
|
+
def subsd(dst, src)
|
1274
|
+
common_arithxmm(dst, src, 0xF2, 0x5C, :subsd)
|
1275
|
+
end
|
1276
|
+
|
1277
|
+
|
1278
|
+
def mulss(dst, src)
|
1279
|
+
common_arithxmm(dst, src, 0xF3, 0x59, :mulss)
|
1280
|
+
end
|
1281
|
+
|
1282
|
+
def mulsd(dst, src)
|
1283
|
+
common_arithxmm(dst, src, 0xF2, 0x59, :mulsd)
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
def divss(dst, src)
|
1287
|
+
common_arithxmm(dst, src, 0xF3, 0x5E, :divss)
|
1288
|
+
end
|
1289
|
+
|
1290
|
+
def divsd(dst, src)
|
1291
|
+
common_arithxmm(dst, src, 0xF2, 0x5E, :divsd)
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
def int3
|
1295
|
+
[0xcc].pack("C")
|
1296
|
+
end
|
1297
|
+
end
|
1298
|
+
end
|