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 CHANGED
@@ -1,3 +1,3 @@
1
1
  require 'mkmf'
2
-
2
+ $CFLAGS += ' -fomit-frame-pointer '
3
3
  create_makefile("ytljit_ext");
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 INT2FIX(raw_arena->body[raw_offset]);
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 = FIX2INT(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 INT2FIX(raw_arena->body);
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 UINT2NUM(*((char *)NUM2LONG(addr)));
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
- static VALUE *
400
- get_registers(unsigned long *regs, VALUE *argv)
401
- {
402
- argv[0] = ULONG2NUM((unsigned long)__builtin_return_address(1));
403
-
404
- /* regs[0] old bp
405
- regs[-1] old ebx (maybe gcc depend)
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(void)
408
+ body(uintptr_t *regbuf)
422
409
  {
423
410
  VALUE *argv;
424
- unsigned long *regs;
425
-
426
- #if defined(__i386__) || defined(__i386)
427
- asm("mov (%%ebp), %0"
428
- : "=r" (regs) : : "%eax");
429
- #elif defined(__x86_64__) || defined(__x86_64)
430
- asm("mov (%%rbp), %0"
431
- : "=r" (regs) : : "%rax");
432
- #else
433
- #error "only i386 or x86-64 is supported"
434
- #endif
435
- argv = ALLOCA_N(VALUE, 8);
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, 8, argv);
424
+ rb_funcall2(ytl_eStepHandler, ytl_v_step_handler_id, NUMREGS + 1, argv);
439
425
  }
440
426
 
441
- static void
427
+ static uintptr_t * __attribute__ ((noinline, optimize("omit-frame-pointer")))
442
428
  pushall(void)
443
429
  {
444
430
  #ifdef __x86_64__
445
- asm("push %rax");
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("pushal");
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("pop %rax");
484
+ asm("push %rax");
470
485
  #elif __i386__
471
- asm("popal");
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
- /* Don't add local variables. Maybe break consistency of stack */
482
-
483
- pushall();
484
- body();
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
@@ -33,6 +33,8 @@ VALUE ytl_arena_size(VALUE);
33
33
  VALUE ytl_arena_address(VALUE);
34
34
  VALUE ytl_arena_to_s(VALUE);
35
35
 
36
+ void ytl_step_handler(void);
37
+
36
38
  void init_csarena();
37
39
  void *csalloc(int);
38
40
  void csfree(void *);
data/lib/ytljit/asm.rb CHANGED
@@ -1,16 +1,49 @@
1
1
  module YTLJit
2
2
 
3
3
  class StepHandler
4
- REG_NAME = ["EAX", "ECX", "EDX", "EBX", "EBP", "ESP", "EDI"]
5
- def step_handler(*regs)
6
- STDERR.print "#{regs[0].to_s(16)} "
7
- STDERR.print CodeSpace.disasm_cache[regs[0].to_s(16)], "\n"
8
- regs.each_with_index do |val, i|
9
- STDERR.print REG_NAME[i]
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 val.to_s(16)
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 do
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
@@ -124,7 +124,7 @@ module YTLJit
124
124
 
125
125
  attr_accessor :used_arg_tab
126
126
  attr :maxargs
127
- attr :area_allocate_pos
127
+ attr_accessor :area_allocate_pos
128
128
 
129
129
  def update_maxargs(args)
130
130
  if @maxargs < args then
@@ -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
- offset = @funcarg_info.area_allocate_pos.pop
181
- if offset then
182
- imm = OpImmidiate8.new(argsize)
183
- code += @asm.update_state(add(SPR, imm))
184
- alloc_argument_area = lambda {
185
- @asm.with_current_address(@asm.output_stream.base_address + offset) {
186
- @asm.output_stream[offset] = sub(SPR, argsize)
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
 
@@ -73,9 +73,9 @@ module YTLJit
73
73
  case dst
74
74
  when OpIndirect
75
75
  case src
76
- when Integer
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
- code += @asm.update_state(add(SPR, OpImmidiate8.new(argsize)))
113
- offset = @funcarg_info.area_allocate_pos.pop
114
- alloc_argument_area = lambda {
115
- asm.with_current_address(asm.output_stream.base_address + offset) {
116
- asm.output_stream[offset] = sub(SPR, argsize)
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
- asm.after_patch_tab.push alloc_argument_area
120
-
121
- @funcarg_info.update_maxargs(argnum)
122
- @funcarg_info.used_arg_tab.pop
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]
@@ -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
@@ -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
- "#{@disp}(#{@reg.to_as})"
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 rm_reg.is_a?(OpRSP) then
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 rm_reg.is_a?(OpRSP) then
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
- case rm.disp
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 rm.reg.is_a?(OpRBP) then
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 rm.reg.is_a?(OpRSP) then
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, rm.disp.value)
517
+ modrm_indirect_off8(regv, rm.reg, rmdisp.value)
509
518
 
510
519
  when OpImmidiate32
511
- modrm_indirect_off32(regv, rm.reg, rm.disp.value)
520
+ modrm_indirect_off32(regv, rm.reg, rmdisp.value)
512
521
 
513
522
  when Integer
514
- if small_integer_8bit?(rm.disp.abs) then
515
- modrm_indirect_off8(regv, rm.reg, rm.disp)
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, rm.disp)
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, 0x0F, 0x10] + modseq).pack("C3#{modfmt}")
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, 0x0F, 0x10] + modseq).pack("C3#{modfmt}")
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, 0x0F, 0x11] + modseq).pack("C3#{modfmt}")
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 + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
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 + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
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 dst.reg_no >= 8 then
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