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.
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