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
data/ext/ytljit.h ADDED
@@ -0,0 +1,285 @@
1
+ #define MAX_DL_HANDLES 10
2
+ #define INIT_CODE_SPACE_SIZE 64
3
+ #define VALUE_SPACE_SIZE (8 * 1024)
4
+
5
+ #define OPEN_CHECK(COND) \
6
+ do { \
7
+ if ((COND) == NULL) { \
8
+ printf("Open failed %d handle", used_dl_handles); \
9
+ } \
10
+ } while(0)
11
+
12
+ struct CodeSpace {
13
+ size_t size;
14
+ size_t used;
15
+ char body[1];
16
+ };
17
+
18
+ VALUE ytl_address_of(VALUE, VALUE);
19
+ VALUE ytl_code_space_allocate(VALUE);
20
+
21
+ void init_csarena();
22
+ void *csalloc(int);
23
+ void csfree(void *);
24
+
25
+ extern VALUE ytl_mYTLJit;
26
+ extern VALUE ytl_cCodeSpace;
27
+ extern VALUE ytl_cValueSpace;
28
+ extern VALUE ytl_cStepHandler;
29
+ extern VALUE ytl_eStepHandler;
30
+
31
+ /* Copy from node.h */
32
+ typedef struct RNode {
33
+ unsigned long flags;
34
+ char *nd_file;
35
+ union {
36
+ struct RNode *node;
37
+ ID id;
38
+ VALUE value;
39
+ VALUE (*cfunc)(ANYARGS);
40
+ ID *tbl;
41
+ } u1;
42
+ union {
43
+ struct RNode *node;
44
+ ID id;
45
+ long argc;
46
+ VALUE value;
47
+ } u2;
48
+ union {
49
+ struct RNode *node;
50
+ ID id;
51
+ long state;
52
+ struct rb_global_entry *entry;
53
+ long cnt;
54
+ VALUE value;
55
+ } u3;
56
+ } NODE;
57
+
58
+
59
+ /* Copy from vm_core.h */
60
+
61
+ struct rb_iseq_struct {
62
+ /***************/
63
+ /* static data */
64
+ /***************/
65
+
66
+ VALUE type; /* instruction sequence type */
67
+ VALUE name; /* String: iseq name */
68
+ VALUE filename; /* file information where this sequence from */
69
+ VALUE filepath; /* real file path or nil */
70
+ VALUE *iseq; /* iseq (insn number and openrads) */
71
+ VALUE *iseq_encoded; /* encoded iseq */
72
+ unsigned long iseq_size;
73
+ VALUE mark_ary; /* Array: includes operands which should be GC marked */
74
+ VALUE coverage; /* coverage array */
75
+ unsigned short line_no;
76
+
77
+ /* insn info, must be freed */
78
+ struct iseq_insn_info_entry *insn_info_table;
79
+ size_t insn_info_size;
80
+
81
+ ID *local_table; /* must free */
82
+ int local_table_size;
83
+
84
+ /* method, class frame: sizeof(vars) + 1, block frame: sizeof(vars) */
85
+ int local_size;
86
+
87
+ struct iseq_inline_cache_entry *ic_entries;
88
+ int ic_size;
89
+
90
+ /**
91
+ * argument information
92
+ *
93
+ * def m(a1, a2, ..., aM, # mandatory
94
+ * b1=(...), b2=(...), ..., bN=(...), # optinal
95
+ * *c, # rest
96
+ * d1, d2, ..., dO, # post
97
+ * &e) # block
98
+ * =>
99
+ *
100
+ * argc = M
101
+ * arg_rest = M+N+1 // or -1 if no rest arg
102
+ * arg_opts = N
103
+ * arg_opts_tbl = [ (N entries) ]
104
+ * arg_post_len = O // 0 if no post arguments
105
+ * arg_post_start = M+N+2
106
+ * arg_block = M+N + 1 + O + 1 // -1 if no block arg
107
+ * arg_simple = 0 if not simple arguments.
108
+ * = 1 if no opt, rest, post, block.
109
+ * = 2 if ambiguos block parameter ({|a|}).
110
+ * arg_size = argument size.
111
+ */
112
+
113
+ int argc;
114
+ int arg_simple;
115
+ int arg_rest;
116
+ int arg_block;
117
+ int arg_opts;
118
+ int arg_post_len;
119
+ int arg_post_start;
120
+ int arg_size;
121
+ VALUE *arg_opt_table;
122
+
123
+ size_t stack_max; /* for stack overflow check */
124
+
125
+ /* catch table */
126
+ struct iseq_catch_table_entry *catch_table;
127
+ int catch_table_size;
128
+
129
+ /* for child iseq */
130
+ struct rb_iseq_struct *parent_iseq;
131
+ struct rb_iseq_struct *local_iseq;
132
+
133
+ /****************/
134
+ /* dynamic data */
135
+ /****************/
136
+
137
+ VALUE self;
138
+ VALUE orig; /* non-NULL if its data have origin */
139
+
140
+ /* block inlining */
141
+ /*
142
+ * NODE *node;
143
+ * void *special_block_builder;
144
+ * void *cached_special_block_builder;
145
+ * VALUE cached_special_block;
146
+ */
147
+
148
+ /* klass/module nest information stack (cref) */
149
+ NODE *cref_stack;
150
+ VALUE klass;
151
+
152
+ /* misc */
153
+ ID defined_method_id; /* for define_method */
154
+
155
+ /* used at compile time */
156
+ struct iseq_compile_data *compile_data;
157
+ };
158
+
159
+ /* Copy from method.h */
160
+ typedef enum {
161
+ NOEX_PUBLIC = 0x00,
162
+ NOEX_NOSUPER = 0x01,
163
+ NOEX_PRIVATE = 0x02,
164
+ NOEX_PROTECTED = 0x04,
165
+ NOEX_MASK = 0x06,
166
+ NOEX_BASIC = 0x08,
167
+ NOEX_UNDEF = NOEX_NOSUPER,
168
+ NOEX_MODFUNC = 0x12,
169
+ NOEX_SUPER = 0x20,
170
+ NOEX_VCALL = 0x40,
171
+ NOEX_RESPONDS = 0x80
172
+ } rb_method_flag_t;
173
+
174
+ #define NOEX_SAFE(n) ((int)((n) >> 8) & 0x0F)
175
+ #define NOEX_WITH(n, s) ((s << 8) | (n) | (ruby_running ? 0 : NOEX_BASIC))
176
+ #define NOEX_WITH_SAFE(n) NOEX_WITH(n, rb_safe_level())
177
+
178
+ /* method data type */
179
+
180
+ typedef enum {
181
+ VM_METHOD_TYPE_ISEQ,
182
+ VM_METHOD_TYPE_CFUNC,
183
+ VM_METHOD_TYPE_ATTRSET,
184
+ VM_METHOD_TYPE_IVAR,
185
+ VM_METHOD_TYPE_BMETHOD,
186
+ VM_METHOD_TYPE_ZSUPER,
187
+ VM_METHOD_TYPE_UNDEF,
188
+ VM_METHOD_TYPE_NOTIMPLEMENTED,
189
+ VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */
190
+ VM_METHOD_TYPE_MISSING /* wrapper for method_missing(id) */
191
+ } rb_method_type_t;
192
+
193
+ typedef struct rb_method_cfunc_struct {
194
+ VALUE (*func)(ANYARGS);
195
+ int argc;
196
+ } rb_method_cfunc_t;
197
+
198
+ typedef struct rb_method_attr_struct {
199
+ ID id;
200
+ VALUE location;
201
+ } rb_method_attr_t;
202
+
203
+ typedef struct rb_iseq_struct rb_iseq_t;
204
+
205
+ typedef struct rb_method_definition_struct {
206
+ rb_method_type_t type; /* method type */
207
+ ID original_id;
208
+ union {
209
+ rb_iseq_t *iseq; /* should be mark */
210
+ rb_method_cfunc_t cfunc;
211
+ rb_method_attr_t attr;
212
+ VALUE proc; /* should be mark */
213
+ enum method_optimized_type {
214
+ OPTIMIZED_METHOD_TYPE_SEND,
215
+ OPTIMIZED_METHOD_TYPE_CALL
216
+ } optimize_type;
217
+ } body;
218
+ int alias_count;
219
+ } rb_method_definition_t;
220
+
221
+ typedef struct rb_method_entry_struct {
222
+ rb_method_flag_t flag;
223
+ char mark;
224
+ rb_method_definition_t *def;
225
+ ID called_id;
226
+ VALUE klass; /* should be mark */
227
+ } rb_method_entry_t;
228
+
229
+ struct unlinked_method_entry_list_entry {
230
+ struct unlinked_method_entry_list_entry *next;
231
+ rb_method_entry_t *me;
232
+ };
233
+
234
+ #define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
235
+
236
+ rb_method_entry_t *rb_method_entry(VALUE klass, ID id);
237
+
238
+ /* Copy from vm_core.h */
239
+
240
+ #define GetCoreDataFromValue(obj, type, ptr) do { \
241
+ ptr = (type*)DATA_PTR(obj); \
242
+ } while (0)
243
+
244
+ typedef struct rb_block_struct {
245
+ VALUE self; /* share with method frame if it's only block */
246
+ VALUE *lfp; /* share with method frame if it's only block */
247
+ VALUE *dfp; /* share with method frame if it's only block */
248
+ rb_iseq_t *iseq;
249
+ VALUE proc;
250
+ } rb_block_t;
251
+
252
+ #define GetProcPtr(obj, ptr) \
253
+ GetCoreDataFromValue(obj, rb_proc_t, ptr)
254
+
255
+ typedef struct {
256
+ rb_block_t block;
257
+
258
+ VALUE envval; /* for GC mark */
259
+ VALUE blockprocval;
260
+ int safe_level;
261
+ int is_from_method;
262
+ int is_lambda;
263
+ } rb_proc_t;
264
+
265
+ #define GetEnvPtr(obj, ptr) \
266
+ GetCoreDataFromValue(obj, rb_env_t, ptr)
267
+
268
+ typedef struct {
269
+ VALUE *env;
270
+ int env_size;
271
+ int local_size;
272
+ VALUE prev_envval; /* for GC mark */
273
+ rb_block_t block;
274
+ } rb_env_t;
275
+
276
+ #define GetBindingPtr(obj, ptr) \
277
+ GetCoreDataFromValue(obj, rb_binding_t, ptr)
278
+
279
+ typedef struct {
280
+ VALUE env;
281
+ VALUE filename;
282
+ unsigned short line_no;
283
+ } rb_binding_t;
284
+
285
+ rb_iseq_t *rb_method_get_iseq(VALUE method);
data/lib/ytljit/asm.rb ADDED
@@ -0,0 +1,205 @@
1
+ module YTLJit
2
+
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]
10
+ STDERR.print ": 0x"
11
+ STDERR.print val.to_s(16)
12
+ STDERR.print " "
13
+ end
14
+ STDERR.print "\n"
15
+ end
16
+ end
17
+
18
+ class Generator
19
+ def initialize(asm)
20
+ @asm = asm
21
+ end
22
+ attr :asm
23
+ end
24
+
25
+ class OutputStream
26
+ def asm=(a)
27
+ @asm = a
28
+ end
29
+
30
+ def base_address
31
+ 0
32
+ end
33
+
34
+ def var_base_address(offset = 0)
35
+ OpVarMemAddress.new(lambda {offset})
36
+ end
37
+ end
38
+
39
+ class FileOutputStream<OutputStream
40
+ def initialize(st)
41
+ @stream = st
42
+ end
43
+
44
+ def emit(code)
45
+ @stream.write(code)
46
+ end
47
+ end
48
+
49
+ class DummyOutputStream<OutputStream
50
+ def initialize(st)
51
+ end
52
+
53
+ def emit(code)
54
+ end
55
+ end
56
+
57
+ class Assembler
58
+ @@value_table_cache = {}
59
+ @@value_table_entity = ValueSpace.new
60
+
61
+ def self.set_value_table(out)
62
+ @@value_table_cache = {}
63
+ @@value_table_entity = out
64
+ end
65
+
66
+ def self.get_value_table(out)
67
+ [@@value_table_entity, @@value_table_cache]
68
+ end
69
+
70
+ def initialize(out, gen = GeneratorExtend)
71
+ @generator = gen.new(self)
72
+ @output_stream = out
73
+ @retry_mode = false
74
+ @step_mode = false
75
+ @asmsend_history = []
76
+
77
+ # Instruction pach table for forwarding reference
78
+ # This is array of proc object.
79
+ @after_patch_tab = []
80
+ reset
81
+ end
82
+
83
+ def reset
84
+ @current_address = @output_stream.base_address
85
+ @offset = 0
86
+ end
87
+
88
+ attr_accessor :current_address
89
+ attr_accessor :step_mode
90
+ attr :offset
91
+ attr :output_stream
92
+ attr :after_patch_tab
93
+ attr :retry_mode
94
+
95
+ def var_current_address
96
+ current_address = @current_address
97
+
98
+ func = lambda {
99
+ current_address
100
+ }
101
+ OpVarMemAddress.new(func)
102
+ end
103
+
104
+ attr_accessor :generated_code
105
+
106
+ def store_outcode(out)
107
+ update_state(out)
108
+ @offset += out.bytesize
109
+ @output_stream.emit(out)
110
+ out
111
+ end
112
+
113
+ def update_state(out)
114
+ @current_address += out.bytesize
115
+ out
116
+ end
117
+
118
+ def with_retry(&body)
119
+ org_base_address = @output_stream.base_address
120
+ yield
121
+
122
+ org_retry_mode = @retry_mode
123
+ @retry_mode = :change_org
124
+ while org_base_address != @output_stream.base_address do
125
+ org_base_address = @output_stream.base_address
126
+ reset
127
+ @output_stream.reset
128
+ @asmsend_history.each do |arg|
129
+ send(arg[0], *arg[1])
130
+ end
131
+ @output_stream.update_refer
132
+ end
133
+
134
+ @after_patch_tab.each do |patproc|
135
+ patproc.call
136
+ end
137
+ @retry_mode = org_retry_mode
138
+ end
139
+
140
+ def add_value_entry(val)
141
+ off= nil
142
+ unless off = @@value_table_cache[val] then
143
+ off = @@value_table_entity.current_pos
144
+ @@value_table_entity.emit([val.value].pack("Q"))
145
+ @@value_table_cache[val] = off
146
+ end
147
+
148
+ @@value_table_entity.var_base_address(off)
149
+ end
150
+
151
+ def add_var_value_retry_func(mn, args)
152
+ if args.any? {|e| e.is_a?(OpVarValueMixin) } and
153
+ @retry_mode == false then
154
+ offset = @offset
155
+ stfunc = lambda {
156
+ with_current_address(@output_stream.base_address + offset) {
157
+ orgretry_mode = @retry_mode
158
+ @retry_mode = :change_op
159
+ out = @generator.send(mn, *args)
160
+ if out.is_a?(Array)
161
+ @output_stream[offset] = out[0]
162
+ else
163
+ @output_stream[offset] = out
164
+ end
165
+ @retry_mode = orgretry_mode
166
+ }
167
+ }
168
+ args.each do |e|
169
+ if e.is_a?(OpVarValueMixin) then
170
+ e.add_refer(stfunc)
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ def method_missing(mn, *args)
177
+ out = @generator.call_stephandler
178
+ store_outcode(out)
179
+
180
+ if @retry_mode == false then
181
+ case mn
182
+ when :call_with_arg
183
+ args.push(@generator.call_with_arg_get_argsize(*args))
184
+ end
185
+ @asmsend_history.push [mn, args]
186
+ end
187
+
188
+ add_var_value_retry_func(mn, args)
189
+ out = @generator.send(mn, *args)
190
+ if out.is_a?(Array) then
191
+ store_outcode(out[0])
192
+ else
193
+ store_outcode(out)
194
+ end
195
+ out
196
+ end
197
+
198
+ def with_current_address(address)
199
+ org_curret_address = self.current_address
200
+ self.current_address = address
201
+ yield
202
+ self.current_address = org_curret_address
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,199 @@
1
+ #---------
2
+ # Extended Specication of Assembler Level Layer
3
+ #
4
+ module YTLJit
5
+ class TypedData
6
+ include AbsArch
7
+
8
+ def initialize(type, ent)
9
+ @type = type
10
+ @entity = ent
11
+ end
12
+
13
+ attr :type
14
+ attr :entity
15
+
16
+ def [](arg)
17
+ TypedData.new(@type[arg], @entity)
18
+ end
19
+
20
+ def gen_access(gen)
21
+ asm = gen.asm
22
+ base = @entity
23
+ case @type
24
+ when AsmType::Scalar, AsmType::Pointer, AsmType::Array
25
+ if base != TMPR then
26
+ code = ""
27
+ code += asm.update_state(gen.mov(TMPR, base))
28
+ [code, @type]
29
+ else
30
+ ["", @type]
31
+ end
32
+
33
+ when AsmType::StructMember
34
+ code = ""
35
+ if base != TMPR then
36
+ code += asm.update_state(gen.mov(TMPR, base))
37
+ end
38
+ oi = OpIndirect.new(TMPR, @type.offset)
39
+ if @type.type.is_a?(AsmType::Array) then
40
+ code += asm.update_state(gen.call_stephandler) if code != ""
41
+ code += asm.update_state(gen.lea(TMPR, oi))
42
+ else
43
+ code += asm.update_state(gen.call_stephandler) if code != ""
44
+ code += asm.update_state(gen.mov(TMPR, oi))
45
+ end
46
+ [code, @type.type]
47
+
48
+ when AsmType::PointedData
49
+ # Now support only index == 0
50
+ code = ""
51
+ if base != TMPR then
52
+ code += asm.update_state(gen.mov(TMPR, base))
53
+ end
54
+ if @type.offset != 0 then
55
+ oi = OpIndirect.new(TMPR, @type.offset)
56
+ code += asm.update_state(gen.call_stephandler) if code != ""
57
+ code += asm.update_state(gen.lea(TMPR, oi))
58
+ end
59
+ ineax = OpIndirect.new(TMPR)
60
+ code += asm.update_state(gen.call_stephandler) if code != ""
61
+ code += asm.update_state(gen.mov(TMPR, ineax))
62
+ [code, @type.type]
63
+ end
64
+ end
65
+ end
66
+
67
+ class FunctionArgument
68
+ def initialize(no, kind)
69
+ @no = no
70
+ @abi_kind = kind
71
+ end
72
+ end
73
+
74
+ class FunctionArgumentInt<FunctionArgument
75
+ case $ruby_platform
76
+ when /x86_64/
77
+ include FunctionArgumentX64MixinCommon
78
+ include FunctionArgumentX64MixinInt
79
+
80
+ when /i.86/
81
+ include FunctionArgumentX86Mixin
82
+ end
83
+ end
84
+
85
+ class FunctionArgumentFloat<FunctionArgument
86
+ case $ruby_platform
87
+ when /x86_64/
88
+ include FunctionArgumentX64MixinCommon
89
+ include FunctionArgumentX64MixinFloat
90
+
91
+ when /i.86/
92
+ include FunctionArgumentX86Mixin
93
+ end
94
+ end
95
+
96
+ class FuncArgInfo
97
+ def initialize
98
+ @maxargs = 0
99
+ @used_arg_tab = []
100
+ @area_allocate_pos = []
101
+ end
102
+
103
+ attr_accessor :used_arg_tab
104
+ attr :maxargs
105
+ attr :area_allocate_pos
106
+
107
+ def update_maxargs(args)
108
+ if @maxargs < args then
109
+ @maxargs = args
110
+ end
111
+ end
112
+ end
113
+
114
+ module GeneratorExtendMixin
115
+ include AbsArch
116
+
117
+ def initialize(asm, handler = "ytl_step_handler")
118
+ super
119
+ @funcarg_info = FuncArgInfo.new
120
+ end
121
+ attr :funcarg_info
122
+
123
+ def nosupported_addressing_mode(inst, dst, src, src2 = nil)
124
+ case inst
125
+ when :mov
126
+ case src
127
+ when TypedData
128
+ orgaddress = @asm.current_address
129
+ rcode = ""
130
+ rcode, rtype = src.gen_access(self)
131
+ if dst != TMPR then
132
+ rcode += @asm.update_state(call_stephandler) if rcode != ""
133
+ rcode += @asm.update_state(mov(dst, TMPR))
134
+ end
135
+ @asm.current_address = orgaddress
136
+ return [rcode, TypedData.new(rtype, dst)]
137
+ end
138
+
139
+ when :seta, :setae, :setb, :setbe, :setl, :setle, :setg, :setge,
140
+ :setna, :setnae, :setnb, :setnbe, :setnc, :setnle,
141
+ :setno, :seto, :setz, :setnz
142
+ case dst
143
+ when OpReg32, OpReg64
144
+ rcode = ""
145
+ reg8 = [AL, CL, DL, BL][dst.reg_no]
146
+ rcode += send(inst, reg8)
147
+ rcode += self.and(dst, 1)
148
+ return rcode
149
+ end
150
+ end
151
+
152
+ case src
153
+ when FunctionArgument
154
+ orgaddress = @asm.current_address
155
+ rcode = ""
156
+ rcode = src.gen_access_src(self, inst, dst, src, src2)
157
+ rcode += @asm.update_state(call_stephandler)
158
+ @asm.current_address = orgaddress
159
+ return rcode
160
+
161
+ when OpRegXMM
162
+ case inst
163
+ when :mov
164
+ return movsd(dst, src)
165
+ end
166
+ end
167
+
168
+ case dst
169
+ when FunctionArgument
170
+ orgaddress = @asm.current_address
171
+ rcode = ""
172
+ rcode = dst.gen_access_dst(self, inst, dst, src, src2)
173
+ rcode += @asm.update_state(call_stephandler)
174
+ @asm.current_address = orgaddress
175
+ return rcode
176
+
177
+ when OpRegXMM
178
+ case inst
179
+ when :mov
180
+ return movsd(dst, src)
181
+ end
182
+ end
183
+
184
+ super
185
+ end
186
+ end
187
+
188
+ class GeneratorExtend<GeneratorIABinary
189
+ include GeneratorExtendMixin
190
+
191
+ case $ruby_platform
192
+ when /x86_64/
193
+ include GeneratorExtendX64Mixin
194
+
195
+ when /i.86/
196
+ include GeneratorExtendX86Mixin
197
+ end
198
+ end
199
+ end