ytljit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/README +29 -0
  2. data/Rakefile +22 -0
  3. data/ext/code_alloc.c +266 -0
  4. data/ext/extconf.rb +3 -0
  5. data/ext/ytljit.c +527 -0
  6. data/ext/ytljit.h +285 -0
  7. data/lib/ytljit/asm.rb +205 -0
  8. data/lib/ytljit/asmext.rb +199 -0
  9. data/lib/ytljit/asmext_x64.rb +212 -0
  10. data/lib/ytljit/asmext_x86.rb +128 -0
  11. data/lib/ytljit/asmutil.rb +182 -0
  12. data/lib/ytljit/codespace.rb +92 -0
  13. data/lib/ytljit/error.rb +7 -0
  14. data/lib/ytljit/instruction.rb +138 -0
  15. data/lib/ytljit/instruction_ia.rb +1298 -0
  16. data/lib/ytljit/instruction_x64.rb +41 -0
  17. data/lib/ytljit/instruction_x86.rb +11 -0
  18. data/lib/ytljit/marshal.rb +133 -0
  19. data/lib/ytljit/matcher.rb +235 -0
  20. data/lib/ytljit/rubyvm.rb +63 -0
  21. data/lib/ytljit/struct.rb +125 -0
  22. data/lib/ytljit/type.rb +112 -0
  23. data/lib/ytljit/util.rb +63 -0
  24. data/lib/ytljit/vm.rb +1649 -0
  25. data/lib/ytljit/vm_codegen.rb +491 -0
  26. data/lib/ytljit/vm_inline_method.rb +85 -0
  27. data/lib/ytljit/vm_inspect.rb +74 -0
  28. data/lib/ytljit/vm_sendnode.rb +561 -0
  29. data/lib/ytljit/vm_trans.rb +508 -0
  30. data/lib/ytljit/vm_type.rb +299 -0
  31. data/lib/ytljit/vm_type_gen.rb +158 -0
  32. data/lib/ytljit/vm_typeinf.rb +98 -0
  33. data/lib/ytljit.rb +46 -0
  34. data/test/asmsample.rb +117 -0
  35. data/test/cstest.rb +61 -0
  36. data/test/marshaltest.rb +27 -0
  37. data/test/test_assemble.rb +148 -0
  38. data/test/test_assemble2.rb +286 -0
  39. data/test/test_codespace.rb +102 -0
  40. data/test/test_typeinf.rb +21 -0
  41. data/test/tivmtest.rb +54 -0
  42. data/test/vmtest.rb +59 -0
  43. data/test/vmtest2.rb +41 -0
  44. data/test/vmtest3.rb +22 -0
  45. data/test/vmtest_compile_only.rb +41 -0
  46. data/test/vmtest_execute_only.rb +22 -0
  47. 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