Class: YTLJit::VM::CompileContext

Inherits:
Object
  • Object
show all
Includes:
AbsArch
Defined in:
lib/ytljit/vm_codegen.rb

Constant Summary

Constants included from AbsArch

AbsArch::AL, AbsArch::BL, AbsArch::CL, AbsArch::DL, AbsArch::FUNC_ARG, AbsArch::FUNC_ARG_YTL, AbsArch::FUNC_FLOAT_ARG, AbsArch::FUNC_FLOAT_ARG_YTL, AbsArch::INDIRECT_BPR, AbsArch::INDIRECT_RETR, AbsArch::INDIRECT_SPR, AbsArch::INDIRECT_TMPR, AbsArch::INDIRECT_TMPR2, AbsArch::INDIRECT_TMPR3

Constants included from SSE

SSE::XMM0, SSE::XMM1, SSE::XMM2, SSE::XMM3, SSE::XMM4, SSE::XMM5, SSE::XMM6, SSE::XMM7

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tnode) ⇒ CompileContext

Returns a new instance of CompileContext.



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/ytljit/vm_codegen.rb', line 234

def initialize(tnode)
  @top_node = tnode
  @prev_context = nil
  @code_space = nil

  # Signature of current compiling method
  # It is array, because method may be nest.
  @current_method_signature = []
  
  # RETR(EAX, RAX) or RETFR(STO, XM0) or Immdiage object
  @ret_reg = RETR
  @ret_reg2 = RETR
  @ret_node = nil
#        @depth_reg = {}
  @depth_reg = Hash.new(0)
  @stack_content = []
  @reg_content = {}

  # Use only type inference compile mode
  @slf = nil

  # Options from user
  @options = {}
end

Instance Attribute Details

#code_spaceObject (readonly)

Returns the value of attribute code_space.



261
262
263
# File 'lib/ytljit/vm_codegen.rb', line 261

def code_space
  @code_space
end

#current_method_signatureObject (readonly)

Returns the value of attribute current_method_signature.



263
264
265
# File 'lib/ytljit/vm_codegen.rb', line 263

def current_method_signature
  @current_method_signature
end

#depth_regObject (readonly)

Returns the value of attribute depth_reg.



265
266
267
# File 'lib/ytljit/vm_codegen.rb', line 265

def depth_reg
  @depth_reg
end

#optionsObject

Returns the value of attribute options.



275
276
277
# File 'lib/ytljit/vm_codegen.rb', line 275

def options
  @options
end

#prev_contextObject

Returns the value of attribute prev_context.



260
261
262
# File 'lib/ytljit/vm_codegen.rb', line 260

def prev_context
  @prev_context
end

#reg_contentObject (readonly)

Returns the value of attribute reg_content.



270
271
272
# File 'lib/ytljit/vm_codegen.rb', line 270

def reg_content
  @reg_content
end

#ret_nodeObject

Returns the value of attribute ret_node.



268
269
270
# File 'lib/ytljit/vm_codegen.rb', line 268

def ret_node
  @ret_node
end

#ret_regObject

Returns the value of attribute ret_reg.



266
267
268
# File 'lib/ytljit/vm_codegen.rb', line 266

def ret_reg
  @ret_reg
end

#ret_reg2Object

Returns the value of attribute ret_reg2.



267
268
269
# File 'lib/ytljit/vm_codegen.rb', line 267

def ret_reg2
  @ret_reg2
end

#slfObject

Returns the value of attribute slf.



273
274
275
# File 'lib/ytljit/vm_codegen.rb', line 273

def slf
  @slf
end

#stack_contentObject

Returns the value of attribute stack_content.



271
272
273
# File 'lib/ytljit/vm_codegen.rb', line 271

def stack_content
  @stack_content
end

#top_nodeObject (readonly)

Returns the value of attribute top_node.



259
260
261
# File 'lib/ytljit/vm_codegen.rb', line 259

def top_node
  @top_node
end

Instance Method Details

#assemblerObject



361
362
363
# File 'lib/ytljit/vm_codegen.rb', line 361

def assembler
  @top_node.asm_tab[@code_space]
end

#cpustack_pop(reg) ⇒ Object



320
321
322
323
324
325
# File 'lib/ytljit/vm_codegen.rb', line 320

def cpustack_pop(reg)
  cont = @stack_content.pop
  if !cont.is_a?(OpRegistor) then
    @reg_content[reg] = cont
  end
end

#cpustack_popn(num) ⇒ Object



342
343
344
345
346
347
# File 'lib/ytljit/vm_codegen.rb', line 342

def cpustack_popn(num)
  wsiz = AsmType::MACHINE_WORD.size
  (num / wsiz).times do |i|
    @stack_content.pop
  end
end

#cpustack_push(reg) ⇒ Object



312
313
314
315
316
317
318
# File 'lib/ytljit/vm_codegen.rb', line 312

def cpustack_push(reg)
  if @reg_content[reg] then
    @stack_content.push @reg_content[reg]
  else
    @stack_content.push reg
  end
end

#cpustack_pushn(num) ⇒ Object



335
336
337
338
339
340
# File 'lib/ytljit/vm_codegen.rb', line 335

def cpustack_pushn(num)
  wsiz = AsmType::MACHINE_WORD.size
  (num / wsiz).times do |i|
    @stack_content.push 1.2
  end
end

#cpustack_setn(offset, val) ⇒ Object



327
328
329
330
331
332
333
# File 'lib/ytljit/vm_codegen.rb', line 327

def cpustack_setn(offset, val)
  if offset >= -@stack_content.size then
    @stack_content[offset] = val
  else
    # Modify previous stack (maybe as arguments)
  end
end

#end_arg_reg(kind = FUNC_ARG) ⇒ Object



456
457
458
459
460
461
462
463
464
465
# File 'lib/ytljit/vm_codegen.rb', line 456

def end_arg_reg(kind = FUNC_ARG)
  asm = assembler
  gen = asm.generator
  used_arg_tab = gen.funcarg_info.used_arg_tab
  if used_arg_tab.last then
    used_arg_tab.last.keys.reverse.each do |rno|
      end_using_reg(kind[rno])
    end
  end
end

#end_using_reg(reg) ⇒ Object



421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/ytljit/vm_codegen.rb', line 421

def end_using_reg(reg)
  case reg
  when OpRegistor
    if reg != TMPR and reg != XMM0 then
      end_using_reg_aux(reg)
    end

  when OpIndirect
    case reg.reg 
    when BPR

    else
      end_using_reg_aux(reg.reg)
    end

  when FunctionArgument
    regdst = reg.dst_opecode
    if regdst.is_a?(OpRegistor) then
      end_using_reg_aux(regdst)
    end
  end
end

#end_using_reg_aux(reg) ⇒ Object



404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
# File 'lib/ytljit/vm_codegen.rb', line 404

def end_using_reg_aux(reg)
  if @depth_reg[reg] then
    @depth_reg[reg] -= 1
  else
    raise "Not saved reg #{reg}"
  end
  if @depth_reg[reg] != -1 then
    assembler.with_retry do
      assembler.pop(reg)
      cpustack_pop(reg)
    end
  else
    @depth_reg[reg] = nil
    @reg_content.delete(reg)
  end
end

#pop_signatureObject



478
479
480
# File 'lib/ytljit/vm_codegen.rb', line 478

def pop_signature
  @current_method_signature.pop
end

#push_signature(signode, method) ⇒ Object



471
472
473
474
475
476
# File 'lib/ytljit/vm_codegen.rb', line 471

def push_signature(signode, method)
  sig = signode.map { |enode|
    enode.decide_type_once(to_signature)
  }
  @current_method_signature.push sig
end

#reset_using_regObject



365
366
367
# File 'lib/ytljit/vm_codegen.rb', line 365

def reset_using_reg
  @depth_reg = Hash.new(0)
end

#set_code_space(cs) ⇒ Object



349
350
351
352
353
354
355
356
357
358
359
# File 'lib/ytljit/vm_codegen.rb', line 349

def set_code_space(cs)
  oldcs = @code_space
  @top_node.add_code_space(@code_space, cs)
  @code_space = cs
  asm = @top_node.asm_tab[cs]
  if asm == nil then
    @top_node.asm_tab[cs] = Assembler.new(cs)
  end

  oldcs
end

#set_reg_content(dst, val) ⇒ Object



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/ytljit/vm_codegen.rb', line 277

def set_reg_content(dst, val)
  if dst.is_a?(FunctionArgument) then
    dst = dst.dst_opecode
  end
  if dst.is_a?(OpRegistor) then
    if val.is_a?(OpRegistor) and @reg_content[val] then
      @reg_content[dst] = @reg_content[val]
    else
      @reg_content[dst] = val
    end
  elsif dst.is_a?(OpIndirect) then
    wsiz = AsmType::MACHINE_WORD.size
    if dst.reg == SPR then
      if val.is_a?(OpRegistor) and @reg_content[val] then
        cpustack_setn(dst.disp.value / wsiz, @reg_content[val])
      else
        cpustack_setn(dst.disp.value / wsiz, val)
      end
    end
    if dst.reg == BPR then
      if val.is_a?(OpRegistor) and @reg_content[val] then
        cpustack_setn(-dst.disp.value / wsiz + 3, @reg_content[val])
      else
        cpustack_setn(-dst.disp.value / wsiz + 3, val)
      end
    end
  elsif dst.is_a?(OpImmidiate) then
    # do nothing and legal

  else
#          pp "foo"
#          pp dst
  end
end

#start_arg_reg(kind = FUNC_ARG) ⇒ Object



444
445
446
447
448
449
450
451
452
453
454
# File 'lib/ytljit/vm_codegen.rb', line 444

def start_arg_reg(kind = FUNC_ARG)
  asm = assembler
  gen = asm.generator
  used_arg_tab = gen.funcarg_info.used_arg_tab
  if used_arg_tab.last then
#          p "#{used_arg_tab.last.keys} #{caller[0]} #{@name}"
    used_arg_tab.last.keys.each do |rno|
      start_using_reg(kind[rno])
    end
  end
end

#start_using_reg(reg) ⇒ Object



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/ytljit/vm_codegen.rb', line 381

def start_using_reg(reg)
  case reg
  when OpRegistor
    if reg != TMPR and reg != XMM0 then
      start_using_reg_aux(reg)
    end

  when OpIndirect
    case reg.reg 
    when BPR

    else
      start_using_reg_aux(reg.reg)
    end

  when FunctionArgument
    regdst = reg.dst_opecode
    if regdst.is_a?(OpRegistor)
      start_using_reg_aux(regdst)
    end
  end
end

#start_using_reg_aux(reg) ⇒ Object



369
370
371
372
373
374
375
376
377
378
379
# File 'lib/ytljit/vm_codegen.rb', line 369

def start_using_reg_aux(reg)
  if @depth_reg[reg] then
    assembler.with_retry do
      assembler.push(reg)
      cpustack_push(reg)
    end
  else
    @depth_reg[reg] = 0
  end
  @depth_reg[reg] += 1
end

#to_signature(offset = -1)) ⇒ Object



467
468
469
# File 'lib/ytljit/vm_codegen.rb', line 467

def to_signature(offset = -1)
  @current_method_signature[offset]
end