ytljit 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|