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