ytljit 0.0.5 → 0.0.6
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/ext/extconf.rb +1 -1
- data/ext/memory.c +3 -3
- data/ext/ytljit.c +87 -48
- data/ext/ytljit.h +2 -0
- data/lib/ytljit/asm.rb +44 -8
- data/lib/ytljit/asmext.rb +1 -1
- data/lib/ytljit/asmext_x64.rb +18 -34
- data/lib/ytljit/asmext_x86.rb +15 -13
- data/lib/ytljit/asmutil.rb +4 -0
- data/lib/ytljit/instruction.rb +8 -1
- data/lib/ytljit/instruction_ia.rb +27 -16
- data/lib/ytljit/instruction_x64.rb +1 -3
- data/lib/ytljit/util.rb +29 -0
- data/lib/ytljit/vm.rb +464 -135
- data/lib/ytljit/vm_codegen.rb +111 -30
- data/lib/ytljit/vm_cruby_obj.rb +12 -10
- data/lib/ytljit/vm_inline_method.rb +32 -4
- data/lib/ytljit/vm_sendnode.rb +292 -38
- data/lib/ytljit/vm_trans.rb +221 -25
- data/lib/ytljit/vm_type.rb +6 -1
- data/lib/ytljit/vm_type_gen.rb +102 -20
- data/test/test_assemble2.rb +11 -8
- metadata +3 -3
data/ext/extconf.rb
CHANGED
data/ext/memory.c
CHANGED
@@ -27,7 +27,7 @@ ytl_arena_ref(VALUE self, VALUE offset)
|
|
27
27
|
raw_arena = (struct Arena *)DATA_PTR(self);
|
28
28
|
raw_offset = FIX2INT(offset);
|
29
29
|
|
30
|
-
return
|
30
|
+
return ULONG2NUM(raw_arena->body[raw_offset]);
|
31
31
|
}
|
32
32
|
|
33
33
|
VALUE
|
@@ -38,7 +38,7 @@ ytl_arena_emit(VALUE self, VALUE offset, VALUE src)
|
|
38
38
|
int raw_offset;
|
39
39
|
|
40
40
|
raw_arena = (struct Arena *)DATA_PTR(self);
|
41
|
-
raw_offset =
|
41
|
+
raw_offset = NUM2ULONG(offset);
|
42
42
|
|
43
43
|
raw_arena->body[raw_offset] = FIX2INT(src);
|
44
44
|
|
@@ -64,7 +64,7 @@ ytl_arena_address(VALUE self)
|
|
64
64
|
|
65
65
|
raw_arena = (struct Arena *)DATA_PTR(self);
|
66
66
|
|
67
|
-
return
|
67
|
+
return ULONG2NUM((uintptr_t)raw_arena->body);
|
68
68
|
}
|
69
69
|
|
70
70
|
|
data/ext/ytljit.c
CHANGED
@@ -213,7 +213,7 @@ ytl_proc_copy(VALUE self, VALUE procval)
|
|
213
213
|
VALUE
|
214
214
|
ytl_memref(VALUE self, VALUE addr)
|
215
215
|
{
|
216
|
-
return
|
216
|
+
return ULONG2NUM(*((uintptr_t *)NUM2LONG(addr)));
|
217
217
|
}
|
218
218
|
|
219
219
|
VALUE
|
@@ -396,93 +396,132 @@ ytl_value_space_to_s(VALUE self)
|
|
396
396
|
return rb_sprintf("#<valueSpace %p base=%p:...>", (void *)self, (void *)raw_cs->body);
|
397
397
|
}
|
398
398
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
regs[-2] return address
|
407
|
-
regs[-3] pusha starts
|
408
|
-
*/
|
409
|
-
argv[1] = ULONG2NUM(regs[-3]); /* eax */
|
410
|
-
argv[2] = ULONG2NUM(regs[-4]); /* ecx */
|
411
|
-
argv[3] = ULONG2NUM(regs[-5]); /* edx */
|
412
|
-
argv[4] = ULONG2NUM(regs[-6]); /* ebx */
|
413
|
-
argv[5] = ULONG2NUM(regs[-7]); /* ebp */
|
414
|
-
argv[6] = ULONG2NUM(regs[-8]); /* esi */
|
415
|
-
argv[7] = ULONG2NUM(regs[-9]); /* edi */
|
416
|
-
|
417
|
-
return argv;
|
418
|
-
}
|
399
|
+
#ifdef __x86_64__
|
400
|
+
#define NUMREGS 16
|
401
|
+
#elif __i386__
|
402
|
+
#define NUMREGS 8
|
403
|
+
#else
|
404
|
+
#error "only i386 or x86-64 is supported"
|
405
|
+
#endif
|
419
406
|
|
420
407
|
static void
|
421
|
-
body(
|
408
|
+
body(uintptr_t *regbuf)
|
422
409
|
{
|
423
410
|
VALUE *argv;
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
argv =
|
436
|
-
argv = get_registers(regs, argv);
|
411
|
+
uintptr_t sp;
|
412
|
+
int i;
|
413
|
+
|
414
|
+
argv = ALLOCA_N(VALUE, NUMREGS + 1);
|
415
|
+
|
416
|
+
for (i = 0; i < NUMREGS; i++) {
|
417
|
+
argv[i] = ULONG2NUM((uintptr_t)regbuf[NUMREGS - i - 1]);
|
418
|
+
}
|
419
|
+
sp = (uintptr_t)regbuf;
|
420
|
+
sp += NUMREGS * sizeof(uintptr_t); /* reg save area */
|
421
|
+
sp += sizeof(uintptr_t); /* stored pc by call instruction */
|
422
|
+
argv[NUMREGS] = ULONG2NUM(sp);
|
437
423
|
|
438
|
-
rb_funcall2(ytl_eStepHandler, ytl_v_step_handler_id,
|
424
|
+
rb_funcall2(ytl_eStepHandler, ytl_v_step_handler_id, NUMREGS + 1, argv);
|
439
425
|
}
|
440
426
|
|
441
|
-
static
|
427
|
+
static uintptr_t * __attribute__ ((noinline, optimize("omit-frame-pointer")))
|
442
428
|
pushall(void)
|
443
429
|
{
|
444
430
|
#ifdef __x86_64__
|
445
|
-
asm("
|
431
|
+
asm("pop %rax");
|
446
432
|
asm("push %rcx");
|
447
433
|
asm("push %rdx");
|
448
434
|
asm("push %rbx");
|
449
435
|
asm("push %rbp");
|
450
436
|
asm("push %rsi");
|
451
437
|
asm("push %rdi");
|
438
|
+
asm("push %r8");
|
439
|
+
asm("push %r9");
|
440
|
+
asm("push %r10");
|
441
|
+
asm("push %r11");
|
442
|
+
asm("push %r12");
|
443
|
+
asm("push %r13");
|
444
|
+
asm("push %r14");
|
445
|
+
asm("push %r15");
|
446
|
+
asm("mov %rax, %rcx"); /* return %rsp */
|
447
|
+
asm("mov %rsp, %rax"); /* return %rsp */
|
448
|
+
asm("push %rcx");
|
452
449
|
#elif __i386__
|
453
|
-
asm("
|
450
|
+
asm("pop %eax");
|
451
|
+
asm("push %ecx");
|
452
|
+
asm("push %edx");
|
453
|
+
asm("push %ebx");
|
454
|
+
asm("push %ebp");
|
455
|
+
asm("push %esi");
|
456
|
+
asm("push %edi");
|
457
|
+
asm("mov %eax, %ecx"); /* return %rsp */
|
458
|
+
asm("mov %esp, %eax"); /* return %rsp */
|
459
|
+
asm("push %ecx");
|
454
460
|
#else
|
455
461
|
#error "only i386 or x86-64 is supported"
|
456
462
|
#endif
|
457
463
|
}
|
458
464
|
|
459
|
-
static void
|
465
|
+
static void __attribute__ ((noinline, optimize("omit-frame-pointer")))
|
460
466
|
popall(void)
|
461
467
|
{
|
462
468
|
#ifdef __x86_64__
|
469
|
+
asm("pop %rax");
|
470
|
+
asm("pop %r15");
|
471
|
+
asm("pop %r14");
|
472
|
+
asm("pop %r13");
|
473
|
+
asm("pop %r12");
|
474
|
+
asm("pop %r11");
|
475
|
+
asm("pop %r10");
|
476
|
+
asm("pop %r9");
|
477
|
+
asm("pop %r8");
|
463
478
|
asm("pop %rdi");
|
464
479
|
asm("pop %rsi");
|
465
480
|
asm("pop %rbp");
|
466
481
|
asm("pop %rbx");
|
467
482
|
asm("pop %rdx");
|
468
483
|
asm("pop %rcx");
|
469
|
-
asm("
|
484
|
+
asm("push %rax");
|
470
485
|
#elif __i386__
|
471
|
-
asm("
|
486
|
+
asm("pop %eax");
|
487
|
+
asm("pop %edi");
|
488
|
+
asm("pop %esi");
|
489
|
+
asm("pop %ebp");
|
490
|
+
asm("pop %ebx");
|
491
|
+
asm("pop %edx");
|
492
|
+
asm("pop %ecx");
|
493
|
+
asm("push %eax");
|
472
494
|
#else
|
473
495
|
#error "only i386 or x86-64 is supported"
|
474
496
|
#endif
|
475
497
|
}
|
476
498
|
|
477
|
-
void
|
499
|
+
void __attribute__ ((optimize("omit-frame-pointer")))
|
478
500
|
ytl_step_handler()
|
479
501
|
{
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
502
|
+
#ifdef __x86_64__
|
503
|
+
asm("push %rax");
|
504
|
+
asm("add $0x8, %rsp");
|
505
|
+
asm("mov %0, %%rax" : : "g"(__builtin_return_address(0)));
|
506
|
+
asm("sub $0x8, %rsp");
|
507
|
+
asm("push %rax");
|
508
|
+
body(pushall());
|
509
|
+
popall();
|
510
|
+
asm("pop %rax");
|
511
|
+
asm("pop %rax");
|
512
|
+
#elif __i386__
|
513
|
+
asm("push %eax");
|
514
|
+
asm("add $0x4, %esp");
|
515
|
+
asm("mov %0, %%eax" : : "g"(__builtin_return_address(0)));
|
516
|
+
asm("sub $0x4, %esp");
|
517
|
+
asm("push %eax");
|
518
|
+
body(pushall());
|
485
519
|
popall();
|
520
|
+
asm("pop %eax");
|
521
|
+
asm("pop %eax");
|
522
|
+
#else
|
523
|
+
#error "only i386 or x86-64 is supported"
|
524
|
+
#endif
|
486
525
|
}
|
487
526
|
|
488
527
|
void
|
data/ext/ytljit.h
CHANGED
data/lib/ytljit/asm.rb
CHANGED
@@ -1,16 +1,49 @@
|
|
1
1
|
module YTLJit
|
2
2
|
|
3
3
|
class StepHandler
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
case $ruby_platform
|
5
|
+
when /x86_64/
|
6
|
+
REGS = {
|
7
|
+
"RAX" => 0, "RCX" => 2, "RDX" => 3, "RBX" => 4,
|
8
|
+
"RBP" => 5, "RSP" => 16, "RDI" => 6, "RSI" => 7,
|
9
|
+
"R8" => 8, "R9" => 9, "R10" => 10, "R11" => 11, "R12" => 12,
|
10
|
+
"R13" => 13, "R14" => 14, "R15" => 15
|
11
|
+
}
|
12
|
+
|
13
|
+
when /i.86/
|
14
|
+
REGS = {
|
15
|
+
"EAX" => 0, "ECX" => 2, "EDX" => 3, "EBX" => 4,
|
16
|
+
"EBP" => 5, "ESP" => 8, "EDI" => 6, "ESI" => 7
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def backtrace(bp)
|
21
|
+
bp = memref(bp)
|
22
|
+
pc = memref(bp + AsmType::MACHINE_WORD.size)
|
23
|
+
frame_struct_tab = VM::Node::TopTopNode.get_frame_struct_tab
|
24
|
+
if frame_struct_tab[pc] then
|
25
|
+
STDERR.print frame_struct_tab[pc][0].class, "\n"
|
26
|
+
STDERR.print frame_struct_tab[pc][0].debug_info, "\n"
|
27
|
+
STDERR.print frame_struct_tab[pc][2].map {|n| n.class}, "\n"
|
28
|
+
bp = memref(bp)
|
29
|
+
backtrace(bp)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def step_handler(*regval)
|
34
|
+
STDERR.print "#{regval[1].to_s(16)} "
|
35
|
+
STDERR.print CodeSpace.disasm_cache[regval[1].to_s(16)], "\n"
|
36
|
+
frame_struct_tab = VM::Node::TopTopNode.get_frame_struct_tab
|
37
|
+
STDERR.print frame_struct_tab[regval[1]][0].debug_info, "\n"
|
38
|
+
STDERR.print frame_struct_tab[regval[1]][2].map {|n| n.class}, "\n"
|
39
|
+
REGS.each do |rname, no|
|
40
|
+
STDERR.print rname
|
10
41
|
STDERR.print ": 0x"
|
11
|
-
STDERR.print
|
42
|
+
STDERR.print regval[no].to_s(16)
|
12
43
|
STDERR.print " "
|
13
44
|
end
|
45
|
+
STDERR.print "\nbacktrace\n"
|
46
|
+
backtrace(regval[5])
|
14
47
|
STDERR.print "\n"
|
15
48
|
end
|
16
49
|
end
|
@@ -94,6 +127,7 @@ module YTLJit
|
|
94
127
|
attr :output_stream
|
95
128
|
attr :after_patch_tab
|
96
129
|
attr :retry_mode
|
130
|
+
attr :generator
|
97
131
|
|
98
132
|
def var_current_address
|
99
133
|
current_address = @current_address
|
@@ -124,10 +158,12 @@ module YTLJit
|
|
124
158
|
|
125
159
|
org_retry_mode = @retry_mode
|
126
160
|
@retry_mode = :change_org
|
127
|
-
while org_base_address != @output_stream.base_address
|
161
|
+
while org_base_address != @output_stream.base_address
|
128
162
|
org_base_address = @output_stream.base_address
|
129
163
|
reset
|
130
164
|
@output_stream.reset
|
165
|
+
@generator.funcarg_info.used_arg_tab = []
|
166
|
+
@generator.funcarg_info.area_allocate_pos = []
|
131
167
|
@asmsend_history.each do |arg|
|
132
168
|
send(arg[0], *arg[1])
|
133
169
|
end
|
data/lib/ytljit/asmext.rb
CHANGED
data/lib/ytljit/asmext_x64.rb
CHANGED
@@ -148,7 +148,7 @@ module YTLJit
|
|
148
148
|
case src
|
149
149
|
when Integer
|
150
150
|
disp = dst.disp
|
151
|
-
dst2 = dst.class.new(dst.reg, disp + 4)
|
151
|
+
dst2 = dst.class.new(dst.reg, disp.value + 4)
|
152
152
|
bit32val = 1 << 32
|
153
153
|
code = mov(dst2, src / bit32val)
|
154
154
|
code += mov(dst, src % bit32val)
|
@@ -162,7 +162,7 @@ module YTLJit
|
|
162
162
|
end
|
163
163
|
|
164
164
|
def call_with_arg_get_argsize(addr, argnum)
|
165
|
-
argnum * 8
|
165
|
+
((argnum > 4) ? argnum : 4 )* 8
|
166
166
|
end
|
167
167
|
|
168
168
|
def call_with_arg(addr, argnum, argsize)
|
@@ -170,47 +170,31 @@ module YTLJit
|
|
170
170
|
|
171
171
|
orgaddress = @asm.current_address
|
172
172
|
code = ""
|
173
|
-
code += @asm.update_state(mov(RAX, OpImmidiate32.new(argnum)))
|
173
|
+
# code += @asm.update_state(mov(RAX, OpImmidiate32.new(argnum)))
|
174
|
+
code += @asm.update_state(mov(RAX, OpImmidiate32.new(0)))
|
174
175
|
code += @asm.update_state(call(addr))
|
175
176
|
callpos = @asm.current_address - @asm.output_stream.base_address
|
176
177
|
if @asm.retry_mode == :change_op then
|
177
178
|
return [code, callpos]
|
178
179
|
end
|
179
180
|
|
180
|
-
|
181
|
-
if
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
@asm.
|
186
|
-
|
181
|
+
# no argument this not allocate 4 words for callee working
|
182
|
+
if argnum != 0 then
|
183
|
+
offset = @funcarg_info.area_allocate_pos.pop
|
184
|
+
if offset then
|
185
|
+
imm = OpImmidiate8.new(argsize)
|
186
|
+
code += @asm.update_state(add(SPR, imm))
|
187
|
+
alloc_argument_area = lambda {
|
188
|
+
@asm.with_current_address(@asm.output_stream.base_address + offset) {
|
189
|
+
@asm.output_stream[offset] = sub(SPR, argsize)
|
190
|
+
}
|
187
191
|
}
|
188
|
-
|
189
|
-
@asm.after_patch_tab.push alloc_argument_area
|
190
|
-
end
|
191
|
-
|
192
|
-
@funcarg_info.update_maxargs(argnum)
|
193
|
-
@funcarg_info.used_arg_tab.pop
|
194
|
-
|
195
|
-
=begin
|
196
|
-
# Save already stored restorer
|
197
|
-
uat = @funcarg_info.used_arg_tab.last
|
198
|
-
while !fainfo.empty? do
|
199
|
-
nreg = fainfo.pop
|
200
|
-
if argpos = ARGPOS2REG.index(nreg) then
|
201
|
-
if uat[argpos] then
|
202
|
-
fainfo.push nreg
|
203
|
-
break
|
204
|
-
else
|
205
|
-
code += @asm.update_state(pop(nreg))
|
206
|
-
uat[argpos] = true
|
207
|
-
end
|
208
|
-
else
|
209
|
-
fainfo.push nreg
|
210
|
-
break
|
192
|
+
@asm.after_patch_tab.push alloc_argument_area
|
211
193
|
end
|
194
|
+
|
195
|
+
@funcarg_info.update_maxargs(argnum)
|
196
|
+
@funcarg_info.used_arg_tab.pop
|
212
197
|
end
|
213
|
-
=end
|
214
198
|
|
215
199
|
@asm.current_address = orgaddress
|
216
200
|
|
data/lib/ytljit/asmext_x86.rb
CHANGED
@@ -73,9 +73,9 @@ module YTLJit
|
|
73
73
|
case dst
|
74
74
|
when OpIndirect
|
75
75
|
case src
|
76
|
-
|
76
|
+
when Integer
|
77
77
|
disp = dst.disp
|
78
|
-
dst2 = dst.class.new(dst.reg, disp + 4)
|
78
|
+
dst2 = dst.class.new(dst.reg, disp.value + 4)
|
79
79
|
bit32val = 1 << 32
|
80
80
|
code = mov(dst2, src / bit32val)
|
81
81
|
code += mov(dst, src % bit32val)
|
@@ -108,18 +108,20 @@ module YTLJit
|
|
108
108
|
if @asm.retry_mode == :change_op then
|
109
109
|
return [code, callpos]
|
110
110
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
asm.output_stream
|
111
|
+
|
112
|
+
if argnum != 0 then
|
113
|
+
code += @asm.update_state(add(SPR, OpImmidiate8.new(argsize)))
|
114
|
+
offset = @funcarg_info.area_allocate_pos.pop
|
115
|
+
alloc_argument_area = lambda {
|
116
|
+
asm.with_current_address(asm.output_stream.base_address + offset) {
|
117
|
+
asm.output_stream[offset] = sub(SPR, argsize)
|
118
|
+
}
|
117
119
|
}
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
asm.after_patch_tab.push alloc_argument_area
|
121
|
+
|
122
|
+
@funcarg_info.update_maxargs(argnum)
|
123
|
+
@funcarg_info.used_arg_tab.pop
|
124
|
+
end
|
123
125
|
@asm.current_address = orgaddress
|
124
126
|
|
125
127
|
[code, callpos]
|
data/lib/ytljit/asmutil.rb
CHANGED
@@ -92,6 +92,8 @@ module YTLJit
|
|
92
92
|
TMPR = OpEAX.instance
|
93
93
|
TMPR2 = OpEDX.instance
|
94
94
|
TMPR3 = OpECX.instance
|
95
|
+
PTMPR = OpEBX.instance
|
96
|
+
THEPR = OpEDI.instance # Temporary Heap pointer
|
95
97
|
DBLLOR = OpEAX.instance
|
96
98
|
DBLHIR = OpEDX.instance
|
97
99
|
RETR = OpEAX.instance
|
@@ -104,6 +106,8 @@ module YTLJit
|
|
104
106
|
# TMPR3 = OpRCX.instance
|
105
107
|
TMPR2 = OpR10.instance
|
106
108
|
TMPR3 = OpR11.instance
|
109
|
+
PTMPR = OpRBX.instance
|
110
|
+
THEPR = OpR14.instance # Temporary Heap pointer
|
107
111
|
DBLLOR = OpRAX.instance
|
108
112
|
DBLHIR = OpRDX.instance
|
109
113
|
RETR = OpRAX.instance
|
data/lib/ytljit/instruction.rb
CHANGED
@@ -116,6 +116,9 @@ module YTLJit
|
|
116
116
|
class OpIndirect<Operand
|
117
117
|
def initialize(reg, disp = 0)
|
118
118
|
@reg = reg
|
119
|
+
if disp.is_a?(Fixnum) then
|
120
|
+
disp = OpImmidiate.new(disp)
|
121
|
+
end
|
119
122
|
@disp = disp
|
120
123
|
end
|
121
124
|
|
@@ -124,7 +127,11 @@ module YTLJit
|
|
124
127
|
|
125
128
|
|
126
129
|
def to_as
|
127
|
-
|
130
|
+
if @disp.is_a?(OpImmidiate) then
|
131
|
+
"#{@disp.value}(#{@reg.to_as})"
|
132
|
+
else
|
133
|
+
"#{@disp.value}(#{@reg.to_as})"
|
134
|
+
end
|
128
135
|
end
|
129
136
|
|
130
137
|
def using(reg)
|
@@ -465,7 +465,8 @@ module YTLJit
|
|
465
465
|
|
466
466
|
def modrm_indirect_off32(regv, rm_reg, rm_disp)
|
467
467
|
fstb = 0b10000000 | ((regv & 7) << 3) | (rm_reg.reg_no & 7)
|
468
|
-
if rm_reg.is_a?(OpESP) or
|
468
|
+
if rm_reg.is_a?(OpESP) or
|
469
|
+
rm_reg.is_a?(OpRSP) or rm_reg.is_a?(OpR12) then
|
469
470
|
[[fstb, 0b00100100, rm_disp], "C2L"]
|
470
471
|
else
|
471
472
|
[[fstb, rm_disp], "CL"]
|
@@ -474,7 +475,8 @@ module YTLJit
|
|
474
475
|
|
475
476
|
def modrm_indirect_off8(regv, rm_reg, rm_disp)
|
476
477
|
fstb = 0b01000000 | ((regv & 7) << 3) | (rm_reg.reg_no & 7)
|
477
|
-
if rm_reg.is_a?(OpESP) or
|
478
|
+
if rm_reg.is_a?(OpESP) or
|
479
|
+
rm_reg.is_a?(OpRSP) or rm_reg.is_a?(OpR12) then
|
478
480
|
[[fstb, 0b00100100, rm_disp], "C3"]
|
479
481
|
else
|
480
482
|
[[fstb, rm_disp], "CC"]
|
@@ -491,13 +493,20 @@ module YTLJit
|
|
491
493
|
regv = reg.value
|
492
494
|
end
|
493
495
|
|
494
|
-
|
496
|
+
rmdisp = rm.disp
|
497
|
+
if rmdisp.class == OpImmidiate then
|
498
|
+
rmdisp = rmdisp.value
|
499
|
+
end
|
500
|
+
|
501
|
+
case rmdisp
|
495
502
|
when 0
|
496
|
-
if rm.reg.is_a?(OpEBP) or
|
503
|
+
if rm.reg.is_a?(OpEBP) or
|
504
|
+
rm.reg.is_a?(OpRBP) or rm.reg.is_a?(OpR13) then
|
497
505
|
modrm_indirect_off8(regv, rm.reg, 0)
|
498
506
|
else
|
499
507
|
fstb = 0b00000000 | ((regv & 7) << 3) | (rm.reg.reg_no & 7)
|
500
|
-
if rm.reg.is_a?(OpESP) or
|
508
|
+
if rm.reg.is_a?(OpESP) or
|
509
|
+
rm.reg.is_a?(OpRSP) or rm.reg.is_a?(OpR12) then
|
501
510
|
[[fstb, 0x24], "C2"]
|
502
511
|
else
|
503
512
|
[[fstb], "C"]
|
@@ -505,16 +514,16 @@ module YTLJit
|
|
505
514
|
end
|
506
515
|
|
507
516
|
when OpImmidiate8
|
508
|
-
modrm_indirect_off8(regv, rm.reg,
|
517
|
+
modrm_indirect_off8(regv, rm.reg, rmdisp.value)
|
509
518
|
|
510
519
|
when OpImmidiate32
|
511
|
-
modrm_indirect_off32(regv, rm.reg,
|
520
|
+
modrm_indirect_off32(regv, rm.reg, rmdisp.value)
|
512
521
|
|
513
522
|
when Integer
|
514
|
-
if small_integer_8bit?(
|
515
|
-
modrm_indirect_off8(regv, rm.reg,
|
523
|
+
if small_integer_8bit?(rmdisp.abs) then
|
524
|
+
modrm_indirect_off8(regv, rm.reg, rmdisp)
|
516
525
|
else
|
517
|
-
modrm_indirect_off32(regv, rm.reg,
|
526
|
+
modrm_indirect_off32(regv, rm.reg, rmdisp)
|
518
527
|
end
|
519
528
|
end
|
520
529
|
end
|
@@ -685,10 +694,11 @@ module YTLJit
|
|
685
694
|
end
|
686
695
|
|
687
696
|
def common_setcc(dst, opc, inst)
|
697
|
+
rexseq, rexfmt = rex(nil, dst)
|
688
698
|
case dst
|
689
699
|
when OpReg8, OpIndirect, OpMem8
|
690
700
|
modseq, modfmt = modrm(inst, 0, dst, dst, nil)
|
691
|
-
([0x0F, opc] + modseq).pack("C2#{modfmt}")
|
701
|
+
(rexseq + [0x0F, opc] + modseq).pack("#{rexfmt}C2#{modfmt}")
|
692
702
|
else
|
693
703
|
return nosupported_addressing_mode(inst, dst, nil)
|
694
704
|
end
|
@@ -709,16 +719,17 @@ module YTLJit
|
|
709
719
|
end
|
710
720
|
|
711
721
|
def common_movssd(dst, src, op, inst)
|
722
|
+
rexseq, rexfmt = rex(dst, src)
|
712
723
|
case dst
|
713
724
|
when OpRegXMM
|
714
725
|
case src
|
715
726
|
when OpRegXMM
|
716
727
|
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
717
|
-
([op
|
728
|
+
([op] + rexseq + [0x0F, 0x10] + modseq).pack("C#{rexfmt}C2#{modfmt}")
|
718
729
|
|
719
730
|
when OpIndirect
|
720
731
|
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
721
|
-
([op
|
732
|
+
([op] + rexseq + [0x0F, 0x10] + modseq).pack("C#{rexfmt}C2#{modfmt}")
|
722
733
|
|
723
734
|
else
|
724
735
|
return nosupported_addressing_mode(inst, dst, src)
|
@@ -728,7 +739,7 @@ module YTLJit
|
|
728
739
|
case src
|
729
740
|
when OpRegXMM
|
730
741
|
modseq, modfmt = modrm(inst, src, dst, dst, src)
|
731
|
-
([op
|
742
|
+
([op] + rexseq + [0x0F, 0x11] + modseq).pack("C#{rexfmt}C2#{modfmt}")
|
732
743
|
|
733
744
|
else
|
734
745
|
return nosupported_addressing_mode(inst, dst, src)
|
@@ -747,7 +758,7 @@ module YTLJit
|
|
747
758
|
rexseq, rexfmt = rex(dst, src)
|
748
759
|
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
749
760
|
if op0 then
|
750
|
-
(rexseq + [
|
761
|
+
([op0] + rexseq + [0x0F, op1] + modseq).pack("C#{rexfmt}C2#{modfmt}")
|
751
762
|
else
|
752
763
|
(rexseq + [0x0F, op1] + modseq).pack("#{rexfmt}C2#{modfmt}")
|
753
764
|
end
|
@@ -756,7 +767,7 @@ module YTLJit
|
|
756
767
|
rexseq, rexfmt = rex(dst, src)
|
757
768
|
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
758
769
|
if op0 then
|
759
|
-
(rexseq + [
|
770
|
+
([op0] + rexseq + [0x0F, op1] + modseq).pack("C#{rexfmt}C2#{modfmt}")
|
760
771
|
else
|
761
772
|
(rexseq + [0x0F, op1] + modseq).pack("#{rexfmt}C2#{modfmt}")
|
762
773
|
end
|
@@ -11,7 +11,6 @@ module YTLJit
|
|
11
11
|
|
12
12
|
if dst.is_a?(OpIndirect) and dst.reg.is_a?(OpReg64) then
|
13
13
|
if dst.reg_no >= 8 then
|
14
|
-
rrex |= 0b1000
|
15
14
|
rrex |= 0b1
|
16
15
|
end
|
17
16
|
end
|
@@ -24,8 +23,7 @@ module YTLJit
|
|
24
23
|
end
|
25
24
|
|
26
25
|
if src.is_a?(OpIndirect) and src.reg.is_a?(OpReg64) then
|
27
|
-
if
|
28
|
-
rrex |= 0b1000
|
26
|
+
if src.reg_no >= 8 then
|
29
27
|
rrex |= 0b1
|
30
28
|
end
|
31
29
|
end
|
data/lib/ytljit/util.rb
CHANGED
@@ -52,10 +52,29 @@ module YTLJit
|
|
52
52
|
# Singleton class can't be marshaled.
|
53
53
|
# So this class wrap to marshal singleton class
|
54
54
|
class ClassClassWrapper
|
55
|
+
@@instance_tab = {}
|
56
|
+
|
57
|
+
def self.instance(clsobj)
|
58
|
+
if clsobj.is_a?(ClassClassWrapper)
|
59
|
+
clsobj = clsobj.value
|
60
|
+
end
|
61
|
+
ins = @@instance_tab[clsobj]
|
62
|
+
if ins == nil then
|
63
|
+
ins = ClassClassWrapper.new(clsobj)
|
64
|
+
@@instance_tab[clsobj] = ins
|
65
|
+
end
|
66
|
+
|
67
|
+
ins
|
68
|
+
end
|
69
|
+
|
55
70
|
def initialize(clsobj)
|
56
71
|
@klass_object = clsobj
|
57
72
|
@value = nil
|
58
73
|
end
|
74
|
+
|
75
|
+
def to_s
|
76
|
+
"#<Ytljit::ClassClassWrapper type=#{value.inspect}"
|
77
|
+
end
|
59
78
|
|
60
79
|
def value
|
61
80
|
if @value then
|
@@ -82,6 +101,16 @@ module YTLJit
|
|
82
101
|
@klass_object = obj
|
83
102
|
@value = nil
|
84
103
|
end
|
104
|
+
|
105
|
+
def superclass
|
106
|
+
sup = value.superclass
|
107
|
+
ins = @@instance_tab[sup]
|
108
|
+
if ins then
|
109
|
+
ins
|
110
|
+
else
|
111
|
+
sup
|
112
|
+
end
|
113
|
+
end
|
85
114
|
end
|
86
115
|
end
|
87
116
|
|