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.



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
# File 'lib/ytljit/vm_codegen.rb', line 282

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 = Hash.new(true)
  @reg_history = Hash.new

  # Use only type inference compile mode
  @slf = nil

  # Options from user
  @options = {}

  # Comment of type inference
  @comment = {}
end

Instance Attribute Details

#code_spaceObject (readonly)

Returns the value of attribute code_space.



313
314
315
# File 'lib/ytljit/vm_codegen.rb', line 313

def code_space
  @code_space
end

#commentObject

Returns the value of attribute comment.



328
329
330
# File 'lib/ytljit/vm_codegen.rb', line 328

def comment
  @comment
end

#current_method_signatureObject (readonly)

Returns the value of attribute current_method_signature.



315
316
317
# File 'lib/ytljit/vm_codegen.rb', line 315

def current_method_signature
  @current_method_signature
end

#depth_regObject (readonly)

Returns the value of attribute depth_reg.



317
318
319
# File 'lib/ytljit/vm_codegen.rb', line 317

def depth_reg
  @depth_reg
end

#optionsObject

Returns the value of attribute options.



327
328
329
# File 'lib/ytljit/vm_codegen.rb', line 327

def options
  @options
end

#prev_contextObject

Returns the value of attribute prev_context.



312
313
314
# File 'lib/ytljit/vm_codegen.rb', line 312

def prev_context
  @prev_context
end

#reg_contentObject (readonly)

Returns the value of attribute reg_content.



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

def reg_content
  @reg_content
end

#ret_nodeObject

Returns the value of attribute ret_node.



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

def ret_node
  @ret_node
end

#ret_regObject

Returns the value of attribute ret_reg.



318
319
320
# File 'lib/ytljit/vm_codegen.rb', line 318

def ret_reg
  @ret_reg
end

#ret_reg2Object

Returns the value of attribute ret_reg2.



319
320
321
# File 'lib/ytljit/vm_codegen.rb', line 319

def ret_reg2
  @ret_reg2
end

#slfObject

Returns the value of attribute slf.



325
326
327
# File 'lib/ytljit/vm_codegen.rb', line 325

def slf
  @slf
end

#stack_contentObject

Returns the value of attribute stack_content.



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

def stack_content
  @stack_content
end

#top_nodeObject (readonly)

Returns the value of attribute top_node.



311
312
313
# File 'lib/ytljit/vm_codegen.rb', line 311

def top_node
  @top_node
end

Instance Method Details

#assemblerObject



417
418
419
# File 'lib/ytljit/vm_codegen.rb', line 417

def assembler
  @top_node.asm_tab[@code_space]
end

#cpustack_pop(reg) ⇒ Object



374
375
376
377
378
379
380
381
# File 'lib/ytljit/vm_codegen.rb', line 374

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

#cpustack_popn(num) ⇒ Object



398
399
400
401
402
403
# File 'lib/ytljit/vm_codegen.rb', line 398

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

#cpustack_push(reg) ⇒ Object



366
367
368
369
370
371
372
# File 'lib/ytljit/vm_codegen.rb', line 366

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



391
392
393
394
395
396
# File 'lib/ytljit/vm_codegen.rb', line 391

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



383
384
385
386
387
388
389
# File 'lib/ytljit/vm_codegen.rb', line 383

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



521
522
523
524
525
526
527
528
529
530
# File 'lib/ytljit/vm_codegen.rb', line 521

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



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
# File 'lib/ytljit/vm_codegen.rb', line 486

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



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
# File 'lib/ytljit/vm_codegen.rb', line 466

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

#pop_signatureObject



543
544
545
# File 'lib/ytljit/vm_codegen.rb', line 543

def pop_signature
  @current_method_signature.pop
end

#push_signature(signode, method) ⇒ Object



536
537
538
539
540
541
# File 'lib/ytljit/vm_codegen.rb', line 536

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

#reset_using_regObject



421
422
423
424
# File 'lib/ytljit/vm_codegen.rb', line 421

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

#set_code_space(cs) ⇒ Object



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

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



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/ytljit/vm_codegen.rb', line 330

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 - 1, @reg_content[val])
      else
        cpustack_setn(-dst.disp.value / wsiz - 1, val)
      end
    elsif dst.reg == BPR then
      if val.is_a?(OpRegistor) and @reg_content[val] then
        # 3 means difference of SP(constructed frame) and BP
        # ref. gen_method_prologue
        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



509
510
511
512
513
514
515
516
517
518
519
# File 'lib/ytljit/vm_codegen.rb', line 509

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



443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/ytljit/vm_codegen.rb', line 443

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



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

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

#to_signature(offset = -1)) ⇒ Object



532
533
534
# File 'lib/ytljit/vm_codegen.rb', line 532

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